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>
相关推荐
brzhang6 小时前
我操,终于有人把 AI 大佬们 PUA 程序员的套路给讲明白了!
前端·后端·架构
止观止7 小时前
React虚拟DOM的进化之路
前端·react.js·前端框架·reactjs·react
goms7 小时前
前端项目集成lint-staged
前端·vue·lint-staged
谢尔登7 小时前
【React Natve】NetworkError 和 TouchableOpacity 组件
前端·react.js·前端框架
Lin Hsüeh-ch'in7 小时前
如何彻底禁用 Chrome 自动更新
前端·chrome
augenstern4169 小时前
HTML面试题
前端·html
张可9 小时前
一个KMP/CMP项目的组织结构和集成方式
android·前端·kotlin
G等你下课10 小时前
React 路由懒加载入门:提升首屏性能的第一步
前端·react.js·前端框架
蓝婷儿11 小时前
每天一个前端小知识 Day 27 - WebGL / WebGPU 数据可视化引擎设计与实践
前端·信息可视化·webgl
然我11 小时前
面试官:如何判断元素是否出现过?我:三种哈希方法任你选
前端·javascript·算法