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


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

<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() },

 -------------------------------------------------------更新-------------------------------------------------------

之前單純的以為是請求數據的生命周期問題,確實也和這個有關,修改之后圖表也顯示了,但那是熱更新,第一次創建實例的時候並不會顯示,什么問題呢?

在網上搜到兩個答案,一個是用 $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/90267595

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

   <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后面的數據是父組件需要傳遞給子組件的數據,判斷有數據了再讓這個子組件進行渲染,這樣問題就完美解決了。

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

------------------------------------------------------更新------------------------------------------------------------

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

每次選擇不同的區域后台返回的數據是不同的,但是頁面並不會刷新,我以為是子組件沒有觀測到數據的變化,所以就給每個子組件加了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

https://www.cnblogs.com/goloving/p/9114389.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

 




 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM