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>
相关推荐
xcLeigh2 分钟前
HTML5超酷响应式视频背景动画特效(六种风格,附源码)
前端·音视频·html5
zhenryx4 分钟前
前端-react(class组件和Hooks)
前端·react.js·前端框架
lv程序媛5 分钟前
el-table表头前几列固定,后面几列根据接口返回的值不同展示不同
javascript·vue.js·elementui
ZwaterZ6 分钟前
el-table-column自动生成序号&&在序号前插入图标
前端·javascript·c#·vue
蒟蒻的贤38 分钟前
vue学习11.21
javascript·vue.js·学习
zhangjr05752 小时前
【HarmonyOS Next】鸿蒙实用装饰器一览(一)
前端·harmonyos·arkts
不爱学习的YY酱2 小时前
【操作系统不挂科】<CPU调度(13)>选择题(带答案与解析)
java·linux·前端·算法·操作系统
木子七2 小时前
vue2-vuex
前端·vue
麻辣_水煮鱼2 小时前
vue数据变化但页面不变
前端·javascript·vue.js
BY—-组态3 小时前
web组态软件
前端·物联网·工业互联网·web组态·组态