最近在做一个项目,需要动态增删echarts画出来的图表,使用的框架是vue和element-ui。
首先说一下dom树的构成:
<el-row v-for="(items, index) in echartsData" :key="items.id">
<div>
<template>
<el-popconfirm
title="确定删除该图表吗?"
@confirm="deleteEcharts(index,items)"
>
<!--标题-->
<span class="title" slot="reference">{{ items.name }}</span>
</el-popconfirm>
</template>
<!--Echarts图表-->
<div class="table" :ref="items.name"></div>
</div>
</el-row>
可以看到我将画图的数据都存放到echartsData中了,它的结构如下:
[{
id: 1,
name: "分系统/子系统/ID",
data:[]
}]
下面说一下页面初始化的过程,主要分为两部分,一部分是初始化页面,一部分是初始化图表,具体如下:
//初始化页面
handleInitPage() {
this.echartsData.forEach((element) => {
this.handleInitChart(element.name, element.data);
});
},
//初始化图表
handleInitChart(chartName, chartData) {
//根据chartName找到对应的div去画图
let chartDom = this.$refs[chartName];
//这里之所以是chartDom[0],是因为我发现chartDom是一个数组,且只包含一个元素
let myChart = this.$echarts.init(chartDom[0]);
let option;
option = {
//echarts的画法因项目而异,且不是本篇的重点,这里就不赘述了
};
option && myChart.setOption(option);
},
对于增加echarts图表,我们只需要在echartsData数组后面push进去一个对象即可,再初始化相应的图表即可。但要注意,一般项目中要求新注入的对象和数组里面的对象不能够重复,这里面我是用name作为判断的依据,注意id不同于index,它标志着每个对象每次进入数组的唯一标识。具体用处后面会介绍。
addEcharts(){
let length = this.echartsData.length;
let tempId = this.echartsData[length-1].id
let temp = {
id: tempId + 1,
name: "分系统2/子系统2/ID",
data:[]
}
this.echartsData.push(temp);
//注意这里要用nextTick,也就是DOM树更改之后再在div上画图,
this.$nextTick(()=>{
this.handleInitChart(temp.name,temp.data);
})
}
删除echarts中需要用到我们刚才说到的echartsData的id,我们知道vue中的页面更新是通过对比新旧DOM的区别完成的,这里我们用id作为key标识div,vue就可以发现我们的div是否发生变化了,对应着最初的HTML页面中下面这部分的编写:
<el-row v-for="(items, index) in echartsData" :key="items.id">
千万注意key不能写成index,否则在删除的时候会发生echarts图表和标题错位的问题,原因就是因为没有正确标识生成图表的div,vue不知道它发生了变化。
具体的删除写法如下:
deleteEcharts(index,items){
// 用 echartsInstance.dispose 销毁实例,防止内存泄漏
let chartDom = this.$refs[items.name];
let myChart = this.$echarts.init(chartDom[0]);
myChart.dispose();
this.echartsData.splice(index,1);
}
至此,就完成了使用vue动态增删echarts图表了~