项目中,el-table中使用row-class-name为某一行添加样式,用span-method合并列或者行,之后,我又在table中用了children树形数据,正确效果如下所示
但是处理数据的时候row-class-name、span-method对应的函数报错了,具体错误就不说了,最后查找到原因是使用树形数据后,因为tabledata项中children元素的存在,row-class-name、span-method方法获取到的rowIndex与tabledata的index是不一样的,tabledata数据如下,tabledata的数据是无序的,哪些item有children,有多少个children都是不确定的。row-class-name等用法参考官方文档:https://element.eleme.cn/#/zh-CN/component/table。
tabledata: [{
id: '0',
functionName: '仓库管理',
value: 0
}, {
id: '1',
functionName: '商品管理',
value: 0,
children: [{
id: '1-1',
functionName: '商品明细',
value: 0
}]
}, {
id: '2',
functionName: '客户入库单',
value: 0,
children: [{
id: '2-1',
functionName: '入库明细',
value: 0
}, {
id: '2-2',
functionName: '入库费用',
value: 0
}]
}, {
id: '3',
functionName: '客户管理',
value: 0
}, {
id: '4',
functionName: '客户列表',
value: 0
}]
id=’1-1’的children渲染之后在表格中的rowIndex是2,但是想当然用tabledata[2]拿到的是id=’2’的数据,我们需要建立列表rowIndex与tabledata数据的索引关系。
实现方式如下
countChildren: function () {
this.childrenList = []
for (let i = 0; i < this.tabledata.length; i++) {
if (this.tabledata[i].children) {
this.childrenList.push(this.tabledata[i].children.length)
} else {
this.childrenList.push(0)
}
}
console.log('childrenList')
console.log(this.childrenList)
this.calculateChildrenIndex()
},
// 计算table元素所占的行index及children的index(如存在的话)
calculateChildrenIndex: function () {
this.childrenIndexList = []
this.indexList = []
for (let i = 0; i < this.childrenList.length; i++) {
// 不是展开行的index
let obj = {}
obj.index = i
this.indexList.push(obj)
// 展开行的index
if (this.childrenList[i]) {
let sum = i
for (let j = 0; j < i; j++) {
sum = sum + this.childrenList[j]
}
console.log('前i项的和+长度')
for (let k = 0; k < this.childrenList[i]; k++) {
this.childrenIndexList.push(sum + k + 1)
let obj = {}
obj.index = i
obj.subIndex = k
this.indexList.push(obj)
}
}
}
console.log('indexlist')
console.log(this.indexList)
console.log(this.childrenIndexList)
}
countChildren(),先计算tabledata的哪些项有children,没有children记0,有children记children的个数,最终得到childrenList: [0, 1, 2, 0, 0]。
calculateChildrenIndex(),两个作用,得到所有children的rowIndex数组childrenIndexList,和rowIndex与数据索引数组indexList。主要思想是,对所有的tabledata项,都创建一个对象push进数组,对象包含主索引index,当tabledata项有children时,根据之前项及children的占位计算出在列表中的rowIndex,并且将主索引和children对应的子索引放到一个对象里,push进数组。遍历完成后,childrenIndexList包含了所有children的列表rowIndex,indexList的长度等于列表渲染出的行数,indexList的索引就对应列表的rowIndex,indexList[i]对应的就是数据索引关系,如果没有children,就只有一个index属性,有children,包含index和subIndex两个属性,这样我们就可以获取到我们所需的数据。
应用如下
// 合并列,注意因为children的存在,列表的index与tabledata的index不是一样的
arraySpanMethod ({ row, rowIndex }) {
if (this.childrenIndexList.indexOf(rowIndex) > -1) {
// 对于展开行不处理,不存在合并情况
return
}
let index = this.indexList[rowIndex].index
let arr = ['仓库管理', '客户管理']
if (arr.indexOf(this.tabledata[index].functionName) > -1) {
return [1, 2]
}
},
// 加深某些行背景色
tableRowClassName ({row, rowIndex}) {
if (this.childrenIndexList.indexOf(rowIndex) > -1) {
// 对于展开行不处理,不存在加深情况
return
}
let index = this.indexList[rowIndex].index
let arr = ['仓库管理', '客户管理']
if (arr.indexOf(this.tabledata[index].functionName) > -1) {
return 'menuRow'
}
return ''
}