vue中使用echarts圖表不顯示解決辦法

在開發vue項目的時候遇到了一個問題,就是echarts圖表不顯示,可是寫死數據的時候他會顯示,想一想這個可能就跟數據請求有關了,我是習慣了在mounted生命週期裏面發送請求,mounted意思是頁面已掛載完成,能夠拿到dom節點了,這也說明echarts圖表的dom結構也會在mounted的時候去掛載,然而這個時候咱們的數據尚未請求回來,天然也就沒法渲染出來了,咱們須要在掛載以前就將數據請求回來,知道了這個相信你們也就知道怎麼解決了,就是將數據請求放在created生命週期中。html

<div class="echarts">
      <newIncreaceEcharts class="newIncreaceEcharts"></newIncreaceEcharts>
      <PostRegion class="PostRegion" :postregiondata=postregiondata :regionlegend=regionlegend></PostRegion>
      <PostType class="PostType" :posttypedata=posttypedata :posttypelegend=posttypelegend></PostType>
      <post-salary class="PostSalary" :salarydata=salarydata :salarylegend=salarylegend></post-salary>
    </div>
created(){ this.querydatastatics() this.postRegion() this.queryworktype() this.querysalary() },

 -------------------------------------------------------更新-------------------------------------------------------vue

以前單純的覺得是請求數據的生命週期問題,確實也和這個有關,修改以後圖表也顯示了,但那是熱更新,第一次建立實例的時候並不會顯示,什麼問題呢?node

在網上搜到兩個答案,一個是用 $nextTick方法,讓它在下一個事件隊列中去渲染。(連接:https://www.jianshu.com/p/bfd940c31493  https://blog.csdn.net/alisa_lisa/article/details/88802471數組

一個是用watch進行了監聽,(連接:https://blog.csdn.net/qq_29918313/article/details/90267595echarts

我試了這兩種方式都很差使,估計是寫法和人家的不一樣,很苦惱,找了一天的bug,但我確定這和數據請求數據與渲染的順序有關,因而嘗試在父組件傳數據給子組件以前進行了判斷。讓它有數據 了再去渲染echarts圖表。代碼以下:dom

   <newIncreaceEcharts class="newIncreaceEcharts" v-if="increasedata.length > 0" :increasedlegend="increasedlegend" :increasedata="increasedata" :xAxisdata="xAxisdata"
      ></newIncreaceEcharts>
      <PostRegion class="PostRegion" v-if="postregiondata.length > 0" :postregiondata="postregiondata" :regionlegend="regionlegend"
      ></PostRegion>
      <PostType class="PostType" v-if="posttypedata.length > 0" :posttypedata="posttypedata" :posttypelegend="posttypelegend"
        
      ></PostType>
      <post-salary class="PostSalary" v-if="salarydata.length > 0" :salarydata="salarydata" :salarylegend="salarylegend"
      ></post-salary>

v-if後面的數據是父組件須要傳遞給子組件的數據,判斷有數據了再讓這個子組件進行渲染,這樣問題就完美解決了。post

但我仍是想知道上面兩種方法的原理,這個真的就是源碼理解能力了,有時間了研究一下,再來補充。this

------------------------------------------------------更新------------------------------------------------------------spa

上面的第一個方法確實可讓圖表在第一次實例化的時候顯示出來,可是咱們的圖表是須要改變區域動態加載數據顯示的,以下圖:.net

每次選擇不一樣的區域後臺返回的數據是不一樣的,可是頁面並不會刷新,我覺得是子組件沒有觀測到數據的變化,因此就給每一個子組件加了watch監聽數據的變化

methods: { newincreacepie() { console.log(this.increasedata); var linechart = this.$echarts.init(this.$refs.newincreace); linechart.setOption({ title: { text: "新增崗位趨勢", left: '20px', top: '20px', }, tooltip: { trigger: "axis", axisPointer: { type: "cross", label: { backgroundColor: "#6a7985", }, }, }, legend: { top: '20px', data: this.increasedlegend, //請求回來的數據
 }, toolbox: { feature: { saveAsImage: {}, }, }, grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true, }, xAxis: [ { type: "category", boundaryGap: false, data: this.xAxisdata, //請求回來的數據
 }, ], yAxis: [ { type: "value", }, ], series: this.increasedata, //請求回來的數據
 }); }, }, watch:{ increasedata:{ handler(newValue, oldValue) { // alert('新增數據監聽') if(oldValue != newValue) { this.newincreacepie() } }, deep: true } },

結果只有第一個圖表能夠更新,可是後面三個都仍是沒有更新,檢查了子組件的數據,發現子組件的數據並無變化,這個watch監聽的時候發現新舊數據同樣也就不會更新視圖,因此就要看看父組件是怎麼傳值給子組件的。

<newIncreaceEcharts class="newIncreaceEcharts" v-if="increasedata.length > 0" :increasedlegend="increasedlegend" :increasedata="increasedata" :xAxisdata="xAxisdata"
      ></newIncreaceEcharts>
      <PostRegion class="PostRegion" v-if="postregiondata.length > 0" :postregiondata="postregiondata" :regionlegend="regionlegend" ref="PostRegion"
      ></PostRegion>
      <PostType class="PostType" v-if="posttypedata.length > 0" :posttypedata="posttypedata" :posttypelegend="posttypelegend"
        
      ></PostType>
      <post-salary class="PostSalary" v-if="salarydata.length > 0" :salarydata="salarydata" :salarylegend="salarylegend"
      ></post-salary>

 

 //崗位區域分佈
 postRegion(){ console.log('postRegion開始執行') let formdata = { 'region_code': this.regionId, } console.log(formdata) formdata = this.$Utils.demoRequest(JSON.stringify(formdata)) this.$http.post('statistics/queryPostNumByRegion.do',formdata).then(res => { let data = JSON.parse(this.$Utils.demoResponse(res.data)) console.log(data) let tempregion = [] let tempregionlegend = [] if(data.result == 0) { let statistics_data = data.statistics_data console.log(statistics_data) for(let i = 0; i < statistics_data.length; i++) { var node = {}; node["value"] = statistics_data[i].totalCount; node["name"] = statistics_data[i].labelDesc; this.postregiondata.push(node); this.regionlegend.push(statistics_data[i].labelDesc) } } }) },
postregiondata和regionlegend都是我要傳給子組件的數據,在這裏我是直接在遍歷的時候將數據放進了要傳的數組裏面。在這種狀況下父組件就觀測不到數組的值是否發生變化,因此
我就想到了用一箇中間變量先接收傳過來的值,而後再將這個中間變量賦值給要傳遞給子組件的這個數組。這樣父組件就能觀測到數據發生了變化,而後傳給子組件。代碼以下
 //崗位區域分佈
 postRegion(){ console.log('postRegion開始執行') let formdata = { 'region_code': this.regionId, } console.log(formdata) formdata = this.$Utils.demoRequest(JSON.stringify(formdata)) this.$http.post('statistics/queryPostNumByRegion.do',formdata).then(res => { let data = JSON.parse(this.$Utils.demoResponse(res.data)) console.log(data) let tempregion = [] let tempregionlegend = [] if(data.result == 0) { let statistics_data = data.statistics_data console.log(statistics_data) for(let i = 0; i < statistics_data.length; i++) { var node = {}; node["value"] = statistics_data[i].totalCount; node["name"] = statistics_data[i].labelDesc; console.log(node) tempregion.push(node); tempregionlegend.push(statistics_data[i].labelDesc) } this.postregiondata = tempregion this.regionlegend = tempregionlegend } }) console.log('postRegion執行完畢') },

總結:

解決echarts圖表不顯示的問題:

1.數據請求不能放在mounted生命週期中。

2.圖表掛載以前判斷一下是否有數據,當數據請求回來之後再進行掛載。或者使用$nextTick方法,讓圖表在下一個tick或者本輪tick的微任務階段掛載。

3.父組件要使用中間變量的方式向子組件傳遞須要的數據。

如上例子中方法

4.在父組件數據發生改變後子組件要作到實時更新,就須要子組件用watch來監聽數據的變化。並且對象類型和數組類型的監聽方式不一樣

數組類型:

 

 

watch:{ increasedata:{ handler(newValue, oldValue) { // alert('新增數據監聽')
        if(oldValue != newValue) { this.newincreacepie() } }, deep: true } },

數組中包含對象類型:

 

 

watch:{ postregiondata:{ handler(newValue, oldValue) {
          for(let i = 0; i < newValue.length; i++) { if(oldValue[i].value != newValue[i].value) { this.postregion() } }
 }, deep: true } },

 文章推薦:https://www.jianshu.com/p/1b7e8a28d836

http://www.javashuo.com/article/p-nhnutdlm-nr.html

https://blog.csdn.net/chaitong2204/article/details/81976112?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

相關文章
相關標籤/搜索