嗨害嗨,好久不见。最近工作上有没遇到什么问题?最近有个小伙伴问我做一个任务就是,在el-table中,点击某一行,这一行下方会出现这一行的所有信息,该怎么做。我解决以后,他说他们得在展开的行里画Echarts图,并不像官方文档里面那样简单只用表单显示数据。
我想了想,首先呢,要说几个el-table的属性。
row-key属性:row-key就是要指定一个key标识这一行的数据,用于优化表格的渲染。
expand-row-keys属性:可以通过该属性设置 表格目前的展开行,需要设置 row-key 属性才能使用,该属性为展开行的 keys 的数组。
expand-change方法:当用户对某一行展开或者关闭的时候会触发该事件。后面会用到,如果此时展开项的数组为空,说明此时,一个都没展开。否则,显示展开的id项,通过id就知道哪些展开了。
type="expand" :设置了 expand
则显示为一个可展开的按钮
好了,现在上代码,template部分:
<template>
<div>
<el-table
:data="tableData"
style="width: 100%"
@row-click="rowClick"
:row-key="getRowKeys"
:expand-row-keys="expands"
@expand-change="expandChange"
ref="tableList"
>
<el-table-column type="expand">
<template slot-scope="props">
<div class="echarts" :id="props.row.id"></div>
</template>
</el-table-column>
<el-table-column label="第一年工资" prop="salary1"></el-table-column>
<el-table-column label="第二年工资" prop="salary2"></el-table-column>
<el-table-column label="第三年工资" prop="salary3"></el-table-column>
<el-table-column label="第四年工资" prop="salary4"></el-table-column>
<el-table-column label="第五年工资" prop="salary5"></el-table-column>
</el-table>
</div>
</template>
然后是script的data部分,我们看看:
data() {
return {
tableData: [
{
id: "12987122",
salary1: 9,
salary2: 14,
salary3: 18,
salary4: 22,
salary5: 25,
},
{
id: "12987123",
salary1: 7,
salary2: 12,
salary3: 16,
salary4: 24,
salary5: 30,
},
{
id: "12987124",
salary1: 17,
salary2: 19,
salary3: 22,
salary4: 30,
salary5: 40,
},
{
id: "12987125",
salary1: 18,
salary2: 24,
salary3: 30,
salary4: 36,
salary5: 50,
},
],
expands: [],
};
},
不难看出,这是一个表格,每一行都是一组数据(包含1-5年工资的数据)。现在,我想在点击这一行的时候,展开下面的echarts图,这个该怎么做呢?我一开始是这样想的,如果我把每一项的图表都初始化出来,显示在下面,通过切换实现。然后试了一下,瞬间打脸。因为一开始没展开的时候,是拿不到dom元素的。
因此,只能换一种方法了。先上代码:methods部分
methods: {
initChart(id) {
//找到这个id对应tableData中第几个
let index = this.tableData.map((item) => item.id).indexOf(id);
// console.log("index:", index);
//声明的dataArr数组,里面存的是这一行的salary1-salary5的数据
let dataArr = [];
dataArr.push(this.tableData[index].salary1);
dataArr.push(this.tableData[index].salary2);
dataArr.push(this.tableData[index].salary3);
dataArr.push(this.tableData[index].salary4);
dataArr.push(this.tableData[index].salary5);
//也可以循环
//console.log("dataArr:", dataArr);以第一个为例,就是[9,14,18,22,25] 用于后面echarts数据画图
//echarts画图
let mychart = this.$echarts.init(document.getElementById(id));
let option;
option = {
xAxis: {
type: "category",
data: ["第一年", "第二年", "第三年", "第四年", "第五年"],
},
yAxis: {
type: "value",
},
series: [
{
name: "显示数据",
data: dataArr,
type: "line",
smooth: true,
animationDuration: 2800,
animationEasing: "cubicInOut",
},
],
};
mychart.setOption(option);
},
rowClick(row) {
//点击行时展开收起
this.$refs.tableList.toggleRowExpansion(row);
},
expandChange(row, expandedRows) {
//查看此时的row和expandedRows
console.log("row:", row); //对象,包括id~salary5的所有值
console.log("expandedRows:", expandedRows); //展开的数组,由于后面的设置,这里长度最大为1.为1时说明刚刚展开了一个。为空说明刚刚取消展开了。
if (expandedRows.length) {
//说明此时是展开的
//找到这个row的id
let id = row.id;
//让所有项收起来,这是做成手风琴accordion的形式
this.expands = [];
//让刚刚展开的项放到expands数组中
if (row) {
this.expands.push(row.id);
}
//在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
this.$nextTick(() => {
//这个id对应上边的row.id
this.initChart(id);
});
} else {
//此时是收起
//收起所有
this.expands = [];
}
},
getRowKeys(row) {
//行数据的key,用于优化table的渲染
return row.id;
},
},
这样是不是一目了然了。不要忘记此时出echarts图的时候,得用$nextTick了哦。还记得它的作用吧:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
再梳理一遍,某一行的展开收起被改变时@expand-change:判断此时函数第二个参数expandedRows的长度。如果长度不为0,则说明刚刚是展开,展开的话,先让所有收起来,再把展开的项展开。只保持点击展开的那一项展开(类似于Accordion手风琴案例)。然后利用展开项的row.id,来进行echarts图的绘制,是不是清楚多了?
以上两张图就是这个示例。快去试一试吧,欢迎在评论区讨论。拜拜,下次见咯!