ElementUI Table合并单元格后,勾选行时,数据错误问题

我们在使用table组件时,一般获取勾选的值时有@selection-change回调可以获取到,但是,这只适用于表格数据没有子数据,如果表格有子数据,可以这样获取,肯定的是不能使用@selection-change获取了

html 复制代码
<template>
  <div>
    <el-table
      :ref="tableRef"
      border
      :data="tableData"
      :row-class-name="tableRowClassName"
      row-key="id"
      :span-method="objectSpanMethod"
      style="width: 100%"
      @cell-mouse-enter="handleCellMouseEnter"
      @cell-mouse-leave="handleCellMouseLeave"
      @select="handleSelect"
      @select-all="handleSelectAll"
    >
      <el-table-column align="center" type="selection" width="55" />
      <el-table-column align="center" label="部门" prop="deptName" width="180" />
      <el-table-column align="center" label="姓名" prop="name" width="180" />
      <el-table-column align="center" label="职位" prop="position" />
      <el-table-column align="center" class-name="small-padding fixed-width" fixed="right" label="操作" width="140">
        <template slot-scope="_scope">
          <el-button size="mini" type="text">修改</el-button>
          <el-button size="mini" type="text">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
  export default {
    name: 'Index',

    data() {
      return {
        tableData: [],
        tableRef: 'table',
        optionKey: {
          parentIdKey: 'parentId',
          childIdKey: 'id',
          subKey: 'users',
        },
        groupData: [
          {
            parentId: 1,
            deptName: '技术部',
            users: [
              { id: 11, name: '张三', position: '高级前端工程师' },
              { id: 12, name: '李四', position: '前端工程师' },
              { id: 13, name: '王五', position: 'UI设计师' },
            ],
          },
          {
            parentId: 2,
            deptName: '市场部',
            users: [
              { id: 21, name: '赵六', position: '营销经理' },
              { id: 22, name: '钱七', position: 'SEO专员' },
            ],
          },
          {
            parentId: 3,
            deptName: '人事部',
            users: [
              { id: 31, name: '王八', position: '招聘经理' },
              { id: 32, name: '吴九', position: '招聘专员' },
            ],
          },

          {
            parentId: 4,
            deptName: '外交',
            users: [
              { id: 41, name: '王琨', position: '外交一' },
              { id: 42, name: '吴飞', position: '外交二' },
            ],
          },
        ],

        currentParentId: '',
      }
    },
    created() {
      this.getList()
    },

    methods: {
      addStripedData(groupData, key) {
        return groupData.map((group, index) => {
          // 如果 group[key] 不存在或长度为0,直接给 group 添加 striped
          if (!group[key] || group[key].length === 0) {
            return {
              ...group,
              striped: index % 2 !== 0,
            }
          }

          // 如果 group[key] 有数据,给每个子项添加 striped
          return {
            ...group,
            [key]: group[key].map((child) => ({
              ...child,
              striped: index % 2 !== 0,
            })),
          }
        })
      },
      /** 查询公告列表 */
      getList() {
        const groupData = this.addStripedData(this.groupData, this.optionKey.subKey)
        this.tableData = groupData.flatMap((row) => {
          // : children 表示将取出的值赋给变量 children
          const { [this.optionKey.subKey]: children, ...outerFields } = row

          if (!children || children.length === 0) {
            return [{ ...outerFields }]
          }
          return children.map((item) => ({
            ...item,
            ...outerFields,
          }))
        })
      },

      objectSpanMethod({ row, column, rowIndex, columnIndex }) {
        // 只在部门列合并
        if (column.property === 'deptName' || column.type === 'selection') {
          // 找到当前行所属的分组
          const group = this.groupData.find((g) => {
            return g[this.optionKey.subKey].some((child) => child[this.optionKey.childIdKey] === row[this.optionKey.childIdKey])
          })

          if (!group) {
            return {
              rowspan: 1,
              colspan: 1,
            }
          }

          // 如果是分组的第一行,返回合并行数
          if (group[this.optionKey.subKey][0][this.optionKey.childIdKey] === row[this.optionKey.childIdKey]) {
            return {
              rowspan: group[this.optionKey.subKey].length,
              colspan: 1,
            }
          } else {
            // 其他行不显示
            return {
              rowspan: 0,
              colspan: 0,
            }
          }
        }
      },

      // 处理单选
      handleSelect(selection, row) {
        const isSelected = selection.some((item) => item[this.optionKey.childIdKey] === row[this.optionKey.childIdKey])
        const groupItems = this.tableData.filter((item) => item[this.optionKey.parentIdKey] === row[this.optionKey.parentIdKey])

        if (isSelected) {
          // 选中:添加同组所有项
          groupItems.forEach((item) => {
            if (!selection.some((selected) => selected[this.optionKey.childIdKey] === item[this.optionKey.childIdKey])) {
              this.$refs.table.toggleRowSelection(item, true)
            }
          })
        } else {
          // 取消选中:移除同组所有项
          groupItems.forEach((item) => {
            this.$refs.table.toggleRowSelection(item, false)
          })
        }

        this.handleSelectedRows(this.$refs[this.tableRef].selection)
      },

      // 处理全选
      handleSelectAll(selection) {
        this.handleSelectedRows(selection)
      },

      handleSelectedRows(selection) {
        const parentIdSet = new Set(selection.map((item) => item[this.optionKey.parentIdKey]))
        //这里就是勾选后获取的正确值
        const result = this.groupData.filter((item) => parentIdSet.has(item[this.optionKey.parentIdKey]))
      },
      //  this.$baseLodash

      tableRowClassName({ row, column, rowIndex, columnIndex }) {
        //逻辑判断决定是否修改样式,如果分组一致则使用同一个样式
        const classNames = []

        // 斑马纹样式
        if (row.striped) {
          classNames.push('striped-bg')
        }

        // 高亮当前父级相关的行
        if (row[this.optionKey.parentIdKey] === this.currentParentId) {
          classNames.push('hover-bg')
        }

        return classNames.join(' ')
      },

      // 鼠标移入
      handleCellMouseEnter(row, column, rowIndex, columnIndex) {
        //标记当前是哪个分组
        this.currentParentId = row[this.optionKey.parentIdKey]
      },
      // 鼠标移出
      handleCellMouseLeave() {
        //移出是清空光标
        this.currentParentId = ''
      },
    },
  }
</script>

<style lang="scss" scoped>
  ::v-deep .el-table {
    .el-table__body .el-table__row {
      &.hover-bg td {
        background-color: #f5f7fa !important;
      }

      &.striped-bg td {
        background-color: #ebebeb;
      }
    }
  }
</style>
相关推荐
easyboot2 小时前
vxetable的表格滚动条加粗功能
前端·javascript·vue.js
C澒2 小时前
供应链产研交付提效:样板间 2.0 从标准化到自动化的全链路落地实践
前端·ai编程
yangyanping201082 小时前
Vue入门到精通五之yarn部署项目
前端·javascript·vue.js
Luna-player2 小时前
npx create-vue 创建 Vue 3 项目的交互式配置界面
前端·javascript·vue.js
还是大剑师兰特2 小时前
const { proxy } = getCurrentInstance() 的正确使用方法
前端·javascript·vue.js
zhengzhengwang2 小时前
react18升级新特性
前端·javascript·react.js
Reisentyan2 小时前
[vue 3]HTML Learn Data Day 8
前端·vue.js·html
程序员小李白2 小时前
ES6详细解析
前端·ecmascript·es6