Vue中使用使用echarts自适应屏幕变化并结合axios更新图表

474 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

介绍

应该是比较常见的操作了,我在之前的项目中首次在Vue中使用echarts,感到这二者结合的便利之余也发现了这其中的某些问题,解决后以此记录

创建echarts图表

template

HTML部分与官网相同,只需要一个div容器即可

<div id="main" ref="main"></div>
  • 该节点可作为Vue2所必须的根节点,进而减少一个无意义的div容器
  • 官网的例子是用原生js获取的DOM节点,Vue中可以使用ref来获取。应避免在Vue中使用document.getElementByxxx()
  • 留一个id可以方便操作样式

script

  1. 将配置信息放到data中,在后续从服务器请求数据后更方便地操作数据
data() {
    return {
        myChart: '',
        option: {
            yAxis: {
                type: 'category',
                data: []
            },
            xAxis: {
                type: 'value'
            },
            series: [
                {
                    data: [],
                    type: 'bar',
                    showBackground: true,
                    backgroundStyle: {
                        color: 'rgba(180, 180, 180, 0.2)'
                    }
                }
            ]
        }
    }
},
  1. 在methods中定义一个函数,用于后续解除事件绑定
  2. 如果不需要解除事件,则不用放在methods里(还是更推荐解除掉,因为Vue单页面应用特点不解绑事件容易出问题)
methods: {
    resize() {
        this.myChart.resize();
    }
}
  1. 在mounted钩子中初始化图标
  2. 注意addEventListener中的事件绑定可以用来在用户改变窗口大小时自适应图表大小,因为echarts在被创建时宽高就已经被决定好了。只有后续调用chart.resize()才可以重新改变大小
mounted() {
    var chartDom = this.$refs.main;
    this.myChart = echarts.init(chartDom);
    for (let i = 0; i < this.item.option.length; i++) {
        this.option.series[0].data.push(this.item.option[i].value)
        this.option.yAxis.data.push(this.item.option[i].name)
    }
    this.myChart.setOption(this.option, true);
    window.addEventListener("resize", this.resize);
}
  1. 最后在beforeDestroy中解绑resize事件
beforeDestroy() {
    window.removeEventListener('resize',this.resize)
},
  1. 如果还有后续因为各种原因更新的参数,则可以对data中的数据进行操作来完成图表的更新
  2. 如果直接赋值的话不用先赋空值
  3. 需要使用this.nextTick()来保证数据更新后才进行绘制图表(Vue将DOM更新安排于函数执行结束后以此减少资源消耗)
watch: {
    item(newValue) {
        this.option.series[0].data = []
        this.option.yAxis.data = []
        for (let i = 0; i < newValue.option.length; i++) {
            this.option.series[0].data.push(newValue.option[i].value)
            this.option.yAxis.data.push(newValue.option[i].name)
        }
        this.$nextTick(() => {
            this.myChart.setOption(this.option, true);
        })
    }
},

注意

  • 本例中item是由父组件传过来的变
  • 注意myChart.setOption中第二个参数,传入true可以让echarts图表开启后续更新
  • 数据更新后可能需要使用this.nextTick()