elementui 的 table 组件回显已选数据时候使用toggleRowSelection 方法的坑点

elementui 的 table 组件回显问题

复制代码
"vue": "^2.7.16",
"element-ui": "^2.15.14",

问题描述:

场景:首先我们是通过接口获取到数据之后 然后将返回的数据回显到表格上面

问题:直接将后端返回的数据循环的通过toggleRowSelection进行回显,发现无法选中!

问题出现的原因

通过 element 源码发现,table 在回显的时候必须使用表格里面的对象(实际是引用的地址),但实际上后端返回的数据对象是另一个对象地址 两者不是一样的 所以无法回显

源码地址:https://github.com/ElemeFE/element/blob/v2.15.14/packages/table/src/util.js

复制代码
export function toggleRowStatus(statusArr, row, newVal) {
  let changed = false;
  const index = statusArr.indexOf(row);
  const included = index !== -1;

  const addRow = () => {
    statusArr.push(row);
    changed = true;
  };
  const removeRow = () => {
    statusArr.splice(index, 1);
    changed = true;
  };

  if (typeof newVal === 'boolean') {
    if (newVal && !included) {
      addRow();
    } else if (!newVal && included) {
      removeRow();
    }
  } else {
    if (included) {
      removeRow();
    } else {
      addRow();
    }
  }
  return changed;
}

在做对比的时候使用了 const index = statusArr.indexOf(row)。

因为table的数据是来自列表接口返回的list,而选中的模版是从详情接口里面获取的,对象的引用改变了。

所以 statusArr.indexOf(row) 找不到对象,toggleRowSelection 不会生效。

所以想要生效,只能将详情的数据取找 table 的数据 将找到的 table 数据通过toggleRowSelection进行回显。

全部代码:

复制代码
<template>
  <div>
    <el-table
      ref="multipleTable"
      :data="tableData"
      tooltip-effect="dark"
      style="width: 100%"
      row-key="id"
      @select="handleSingleSelect"
    >
      <el-table-column
        type="selection"
        width="55"
        reserve-selection
      ></el-table-column>
      <el-table-column label="日期" width="120">
        <template slot-scope="scope">{{ scope.row.date }}</template>
      </el-table-column>
      <el-table-column prop="id" label="id" width="120"></el-table-column>
      <el-table-column prop="name" label="姓名" width="120"></el-table-column>
      <el-table-column
        prop="address"
        label="地址"
        show-overflow-tooltip
      ></el-table-column>
    </el-table>
    <div style="margin-top: 20px">
      <span>需要回显的数据</span>
      <br>
      <div v-for="(item, index) in beforeSelect" :key="index">{{ item }}</div>
    </div>
    <div style="margin-top: 20px">
      <el-button @click="clearAllSelection()">清除所有选中</el-button>
      <el-button @click="correctDisplayBeforeSelection()">
        回显之前选中的数据(正确的方式)
      </el-button>
      <el-button @click="errorDisplayBeforeSelection()">
        回显之前选中的数据(错误的方式)
      </el-button>
      <br>
      ------------
      <br>
      <el-button @click="getResponseSelectionData()">
        模拟后端返回的数据
      </el-button>
      <el-button @click="correctResponseDisplayBeforeSelection()">
        回显后端返回的的数据(正确的方式)
      </el-button>
      <el-button @click="errorResponseDisplayBeforeSelection()">
        回显后端返回的的数据(错误的方式)
      </el-button>
      <br>
      <br>
      <el-button @click="clearBeforeSelection()">
        清空需要回显的数据
      </el-button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
          id: 0,
        },
        {
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
          id: 1,
        },
        {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
          id: 2,
        },
        {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
          id: 3,
        },
        {
          date: '2016-05-08',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
          id: 4,
        },
        {
          date: '2016-05-06',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
          id: 5,
        },
        {
          date: '2016-05-07',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
          id: 6,
        },
      ],
      multipleSelection: [],
      beforeSelect: [],
    };
  },

  methods: {
    clearAllSelection() {
      this.$refs.multipleTable.clearSelection();
    },
    correctDisplayBeforeSelection() {
      this.beforeSelect.forEach((s) => {
        this.$refs.multipleTable.toggleRowSelection(s, true);
      });
    },
    errorDisplayBeforeSelection() {
      const copyData = JSON.parse(JSON.stringify(this.beforeSelect))
      copyData.forEach((s) => {
        this.$refs.multipleTable.toggleRowSelection(s, true);
      });
    },
    getResponseSelectionData() {
      const responseData = [
        {
          // date: '2016-05-06',
          // name: '王小虎',
          // address: '上海市普陀区金沙江路 1518 弄',
          id: 5,
        },
        {
          // date: '2016-05-07',
          // name: '王小虎',
          // address: '上海市普陀区金沙江路 1518 弄',
          id: 6,
        },
      ];
      this.beforeSelect = responseData
    },
    handleSingleSelect(selection) {
      console.log('selection', selection);
      this.beforeSelect = selection;
    },
    clearBeforeSelection() {
      this.beforeSelect = []
    },
    errorResponseDisplayBeforeSelection() {
      this.beforeSelect.forEach((s) => {
        this.$refs.multipleTable.toggleRowSelection(s, true);
      });
    },
    correctResponseDisplayBeforeSelection() {
      this.tableData.forEach(s => {
        this.beforeSelect.forEach(v => {
          if (s.id === v.id) {
            this.$refs.multipleTable.toggleRowSelection(s, true);
          }
        })
      })
    }
  },
};
</script>
相关推荐
失忆爆表症1 小时前
05_UI 组件库集成指南:Shadcn/ui + Tailwind CSS v4
前端·css·ui
小迷糊的学习记录1 小时前
Vuex 与 pinia
前端·javascript·vue.js
发现一只大呆瓜1 小时前
前端性能优化:图片懒加载的三种手写方案
前端·javascript·面试
不爱吃糖的程序媛2 小时前
Flutter 与 OpenHarmony 通信:Flutter Channel 使用指南
前端·javascript·flutter
利刃大大2 小时前
【Vue】Element-Plus快速入门 && Form && Card && Table && Tree && Dialog && Menu
前端·javascript·vue.js·element-plus
NEXT062 小时前
AI 应用工程化实战:使用 LangChain.js 编排 DeepSeek 复杂工作流
前端·javascript·langchain
念风零壹2 小时前
AI 时代的前端技术:从系统编程到 JavaScript/TypeScript
前端·ai
光影少年3 小时前
react的hooks防抖和节流是怎样做的
前端·javascript·react.js
小毛驴8503 小时前
Vue 路由示例
前端·javascript·vue.js
发现一只大呆瓜3 小时前
AI流式交互:SSE与WebSocket技术选型
前端·javascript·面试