解决el-table使用树形数据导致的rowIndex数据处理问题

    项目中,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 ''
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要删除 el-table 树形数据中的当前行,可以使用以下步骤: 1. 首先,在当前行上添加一个删除按钮或其他交互元素。你可以使用 el-table-column 的自定义模板来实现这一点。 2. 在点击删除按钮获取当前行的数据。你可以使用 $refs 属性引用 el-table 组件,并使用 $refs.table.getCurrentRow() 方法获取当前行数据。 3. 在获取到当前行数据后,你需要使用递归的方式删除当前行及其所有子行。可以编写一个递归函数,遍历当前行的子节点,将其从数据源中删除。 4. 最后,更新 el-table 组件的数据源,以反映删除操作的结果。可以使用 Vue.set() 方法来更新数据源,确保删除操作能够触发响应式更新。 以下是一个示例代码片段,演示如何删除 el-table 树形数据中的当前行: ```html <template> <el-table :data="tableData" ref="table" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @row-remove="handleRowRemove"> <el-table-column label="名称" prop="name"></el-table-column> <el-table-column label="操作"> <template slot-scope="scope"> <el-button v-if="scope.row.hasChildren" type="text" @click="handleRemoveRow(scope.row)">删除</el-button> </template> </el-table-column> </el-table> </template> <script> export default { data() { return { tableData: [ { name: '节点1', children: [ { name: '子节点1', hasChildren: false }, { name: '子节点2', hasChildren: false } ], hasChildren: true }, { name: '节点2', children: [ { name: '子节点3', hasChildren: true, children: [ { name: '子节点4', hasChildren: false } ] } ], hasChildren: true } ] } }, methods: { handleRemoveRow(row) { this.$refs.table.remove(row) }, handleRowRemove(row, rowIndex) { this.recursiveRemove(row) }, recursiveRemove(row) { for (let i = 0; i < row.children.length; i++) { this.recursiveRemove(row.children[i]) } const parent = this.getParentNode(row) const index = parent.children.indexOf(row) parent.children.splice(index, 1) Vue.set(parent, 'children', parent.children) }, getParentNode(row) { const stack = [this.tableData[0]] while (stack.length) { const node = stack.pop() if (node.children && node.children.indexOf(row) !== -1) { return node } if (node.children) { for (let i = 0; i < node.children.length; i++) { stack.push(node.children[i]) } } } return null } } } </script> ``` 在上述示例中,我们使用 el-button 按钮作为删除交互元素,并在 @click 事件中调用 handleRemoveRow 方法。在 handleRemoveRow 方法中,我们使用 this.$refs.table.remove(row) 方法删除当前行。在 handleRowRemove 方法中,我们调用 recursiveRemove 方法递归地删除当前行及其子行。最后,我们使用 Vue.set() 方法更新数据源,以确保删除操作能够触发响应式更新。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值