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>
相关推荐
漂流瓶jz7 小时前
Webpack如何实现万物皆可import?loader的使用/配置/手写实践
前端·javascript·webpack
ZC跨境爬虫7 小时前
跟着 MDN 学CSS day_41:显式轨道、隐式网格与区域命名放置
前端·javascript·css·ui·交互
修己xj8 小时前
告别手动存图!这款叫 Fatkun 的浏览器插件,简直是素材收集神器
前端
袋鼠云数栈9 小时前
从前端到基础设施,ACOS 如何打通企业全链路可观测
运维·前端·人工智能·数据治理·数据智能
AskHarries9 小时前
系统提示词、开发者指令和用户输入的优先级
java·前端·数据库
Moment9 小时前
长上下文会最终杀死 Rag 吗?
前端·javascript·后端
qcx239 小时前
【系统学AI】25 论文导读 ①:两篇改变 AI 的开山之作——Attention Is All You Need & ReAct
前端·人工智能·react.js·transformer
kyriewen10 小时前
大文件上传最全指南:分片、断点续传、秒传,一篇就够了
前端·javascript·面试
郑洁文11 小时前
基于Python的Web命令执行漏洞自动化检测系统
前端·python·网络安全·自动化
新酱爱学习11 小时前
手搓 10 个 Skill 后,我把重复劳动收敛成了一套零依赖 CLI 工具
前端·javascript·人工智能