最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vuex進(jìn)行Echarts數(shù)據(jù)頁面初始化后如何更新dom

 更新時間:2023年11月18日 14:06:01   作者:Gundam-  
這篇文章主要為大家詳細(xì)介紹了使用Vuex做Echarts數(shù)據(jù)時,當(dāng)頁面初始化后如何更新dom,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下

需求

子組件只裝載數(shù)據(jù),不進(jìn)行HTTP請求,父組件在created的時候,拿到數(shù)據(jù)之后,并存入到store中,要求在異步I/O操作之后再重新渲染dom

問題描述

子組件為echarts圖表,當(dāng)子組件取數(shù)據(jù)時,由于echarts圖表dom已經(jīng)渲染,異步I/O操作在頁面渲染之后才會將數(shù)據(jù)存入store中,使用computed計算屬性獲取object,初值為{},當(dāng)頁面渲染完成,計算得到object不能被watch屬性監(jiān)聽,故不能將新計算出數(shù)據(jù)重新渲染并顯示在頁面中(只針對echarts初始化渲染dom為初值,數(shù)據(jù)修改之后無法響應(yīng)式修改的問題)

代碼分析

// vuex
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    obj: {
      success: 0,
      error: 0,
      pending: 0
    }
  },
  mutations: {
    setObj (state, data) {
      state.obj.success = data.success
      state.obj.error = data.error
      state.obj.pending = data.pending
    }
  },
  actions: {
  },
  modules: {
  }
})

子組件

<template>
  <div>
    i'm test page
    <div ref="basicBarChart" style="width:100%;height:350px">
    </div>
  </div>
</template>
<script>
// import { mapState } from 'vuex'
export default {
  data () {
    return {
    }
  },
  mounted () {
    this.renderBarChart()
  },
  methods: {
    renderBarChart () {
      const chart = this.$refs.basicBarChart
      const myChart = this.$echarts.init(chart)
      if (myChart) {
        myChart.setOption({
          tooltip: {
            trigger: 'item',
            formatter: '{a} <br/> : {c} (wppm3vysvbp%)'
          },
          legend: {
            orient: 'vertical',
            left: 'left ',
            data: ['成功', '失敗', '驗證']
          },
          series: [
            {
              name: '測試',
              type: 'pie',
              radius: '55%',
              data: [
                { value: this.obj.success, name: '成功' },
                { value: this.obj.error, name: '失敗' },
                { value: this.obj.pending, name: '驗證' }
              ],
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        })
        window.addEventListener('resize', function () {
          myChart.resize()
        })
      }
      this.$on('hook:destroyed', () => {
        window.removeEventListener('resize', function () {
          myChart.resize()
        })
      })
    }
  },
  computed: {
    obj () {
      return this.$store.state.obj
    }
  },
  watch: {
    obj (newVal, oldVal) {
      console.log(newVal)
    }
  }
}
</script>

父組件

<template>
<div>
  <my-add></my-add>
</div>
</template>
<script>
import add from '@/components/add'
export default {
  data () {
    return {
    }
  },
  mounted () {
    this.getTest()
  },
  beforeDestroy () {
    this.$store.commit('count/setObj', { success: 0, error: 0, pending: 0 })
  },
  methods: {
    async getTest () {
      setTimeout(() => {
        this.$store.commit('setObj', { success: Math.ceil(Math.random() * 100), error: Math.ceil(Math.random() * 100), pending: Math.ceil(Math.random() * 100) })
      }, 2000)
    }
  },
  components: {
    'my-add': add
  }
}
</script>

效果圖如下,可以看到echarts圖表未更新,這里模擬了一個異步操作,2s之后,父組件才把數(shù)據(jù)寫入store中

我們知道,computed屬性的數(shù)據(jù)為響應(yīng)式數(shù)據(jù),那么為什么echarts圖表未更新呢?我們看代碼

<script>
// import { mapState } from 'vuex'
export default {
  data () {
    return {
    }
  },
  mounted () {
    this.renderBarChart()
  },
  methods: {
    renderBarChart () {
    }
  },
  computed: {
    obj () {
      return this.$store.state.obj
    }
  }
}
</script>

dom渲染之后,也就是mounted的時候,調(diào)用renderBarChart函數(shù),這個時候?qū)om進(jìn)行渲染,而正在這個時候,computed計算出來的值為初值obj:{success: 0,error: 0,pending: 0},而就在這時就已經(jīng)渲染dom到頁面上,而當(dāng)?shù)玫秸嬲臄?shù)據(jù)之后,dom已經(jīng)渲染完成了,而我們使用renderBarChart函數(shù)中的數(shù)據(jù)雖然是響應(yīng)式數(shù)據(jù),但是需要再調(diào)用一次這個函數(shù)才能重新渲染這個dom

解決方法

那么如何重新渲染這個dom呢?

0x1 聲明式渲染&&update鉤子

最簡單的做法是將變量obj放置在dom中,因為obj為響應(yīng)式數(shù)據(jù),當(dāng)obj在dom里發(fā)生改變,隨即調(diào)用update鉤子,dom被修改,再手動調(diào)用renderBarChart函數(shù)將echarts的canvas dom重新渲染

子組件

<template>
  <div>
    i'm test page
    {{obj}}
    <div ref="basicBarChart" style="width:100%;height:350px"></div>
  </div>
</template>
<script>
    export default{
        updated(){
           this.renderBarChart() 
        },
        // ...略
    }
</script>

初始化頁面

異步I/O得到數(shù)據(jù)之后

當(dāng)然,將數(shù)據(jù)放置在dom中,是很影響美觀的,這時候可以使用css display:none修飾一下

 <div style="display:none">{{obj}}</div>

0x2 深度監(jiān)聽

Vue中的watch 方法其實默認(rèn)寫的是handler函數(shù),Vue.js會去處理這個邏輯,最終編譯出來其實就是這個handler

Vue 不能檢測到對象屬性的添加或刪除。由于 Vue 會在初始化實例時對屬性執(zhí)行 getter/setter 轉(zhuǎn)化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉(zhuǎn)換它,這樣才能讓它是響應(yīng)的,默認(rèn)情況下 handler 只監(jiān)聽obj這個屬性它的引用的變化,我們只有整個obj賦值的時候它才會監(jiān)聽到

如果我們需要監(jiān)聽obj里的屬性的值呢?這時候就要用上deep屬性了

<template>
  <div>
    i'm test page
    {{obj}}
    <div ref="basicBarChart" style="width:100%;height:350px"></div>
  </div>
</template>
<script>
  export default{
    // ...略
    watch:{
      obj:{
        handler(newVal,oldVal){
          console.log('我準(zhǔn)備調(diào)用renderBarChart函數(shù)了')
          this.renderBarChart()
        },
        deep:true
      }
    }
}
</script>

深度監(jiān)聽肯定是會消耗資源的,當(dāng)object里內(nèi)嵌object,監(jiān)聽器會一層層的往下遍歷,給對象的所有屬性都加上這個監(jiān)聽器,任何修改obj里面任何一個屬性都會觸發(fā)這個監(jiān)聽器里的 handler

但是這樣不用修改Vuex中的代碼,適合object里屬性少,且無引用類型

0x3 修改obj引用

當(dāng)object的引用發(fā)生變化,那么watch就能監(jiān)聽得到object的變化

修改Vuex的代碼

// vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
  state: {
    obj: {}
  },
  mutations: {
    setObj (state, data) {
      state.obj = data
    }
  },
  actions: {
  },
  modules: {
  }
})

推薦使用第三種方法,直接修改對象引用,這樣直接監(jiān)聽整個object比深度監(jiān)聽開銷更小

以上就是Vuex進(jìn)行Echarts數(shù)據(jù)頁面初始化后如何更新dom的詳細(xì)內(nèi)容,更多關(guān)于Vuex更新dom的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

河源市| 常德市| 沐川县| 井研县| 永福县| 竹北市| 松桃| 镇坪县| 文水县| 鸡东县| 海淀区| 奎屯市| 延川县| 西昌市| 江口县| 安溪县| 邯郸市| 三原县| 招远市| 时尚| 电白县| 上饶市| 天等县| 霞浦县| 南京市| 马龙县| 佳木斯市| 漳州市| 宣威市| 浮山县| 达日县| 荆门市| 乌兰县| 鄂托克前旗| 南溪县| 威海市| 三台县| 辽阳市| 济宁市| 林芝县| 滨海县|