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

相关文章
相关标签/搜索