问题:
Element-ui中,表格(Table)的 toggleRowSelection 方法无法默认选中的情况。
需求:对将设置为选中的内容进行部分修改,如:默认选中的内容必须得通过接口或者其他方式来获取,然后再默认选中。
官方代码:
<template> <div class="wrap"> <el-table border ref="multipleTable" :data="tableData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55"></el-table-column> <el-table-column label="日期" width="120"> <template slot-scope="scope">{{ scope.row.date }}</template> </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"> <el-button @click="toggleSelection([tableData[1], tableData[2]])">切换第二、第三行的选中状态</el-button> <el-button @click="toggleSelection()">取消选择</el-button> </div> </div> </template> <script> export default { data() { return { tableData: [{ date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-08', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-06', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-07', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }], multipleSelection: [] } }, methods: { toggleSelection(rows) { if (rows) { rows.forEach(row => { this.$refs.multipleTable.toggleRowSelection(row); }); } else { this.$refs.multipleTable.clearSelection(); } }, handleSelectionChange(val) { this.multipleSelection = val; } } } </script> <style lang="stylus" scoped> .wrap{ padding: 10px; } </style>
上面的代码就是官方代码,使用效果如下:
从图中看,确实可进行默认选中;
默认选中的内容得通过接口或者其他方式获取,然后再默认选中。示例代码如下:
<template> <div class="wrap"> <el-table border ref="multipleTable" :data="tableData" tooltip-effect="dark" style="width: 100%"> <el-table-column type="selection" width="55"></el-table-column> <el-table-column label="日期" width="120"> <template slot-scope="scope">{{ scope.row.date }}</template> </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"> <el-button @click="toggleSelection">切换</el-button> </div> </div> </template> <script> export default { data() { return { tableData: [{ date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-08', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-06', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-07', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }], // 假如是通过接口或者其他形势获得的某个选中行内容,注意这里多了几个字段 multipleSelection: [ { date: "2016-05-07", name: "王小虎", address: "上海市普陀区金沙江路 1518 弄", description: '这里是描述', type: '类型', id: 'aaaaa111111' } ] } }, methods: { toggleSelection() { // 提取出table表行字段对应的字段 this.multipleSelection.forEach(row => { const obj = { date: row.date, name: row.name, address: row.address }; this.$refs.multipleTable.toggleRowSelection(obj,true); }); }, } } </script> <style lang="stylus" scoped> .wrap{ padding: 10px; } </style>
理论上,上面的内容应该能让表格中的最一列进行选中,然而现实是不行的。
从上面可以看出,首部有选择效果,但却未选中相对应的内容。
解决方法:
从列表(tableData)中找到需要选中的对象,把它筛选出来作为选中的项。注意:寻找的字段要唯一;
因此,我们将上面的方法改为如下的写法就可以了。
methods: { toggleSelection() { this.multipleSelection.forEach(row => { this.$refs.multipleTable.toggleRowSelection( this.tableData.find(item => { return row.date == item.date;} ),true); }); } }
补充:另一种无法选中的情况
原因:在于 vue 组件和表格的渲染顺序问题,代码执行的时候页面渲染还未完成。(如:表格放在 dialog 之类的弹出框里面);
解决方式:在外层加个 $nextTick 即可;传送门:Vue中 $nextTick() 与 Vue.nextTick() 原理及使用
toggleSelection() { this.$nextTick(() => { this.multipleSelection.forEach(row => { this.$refs.multipleTable.toggleRowSelection( this.tableData.find(item => {return row.date == item.date; } ),true); }); }) }
分析:
现在对官方示例分析:
toggleSelection(rows) { if (rows) { rows.forEach(row => { console.log(row); // 这里仅仅加了个打印操作 this.$refs.multipleTable.toggleRowSelection(row); }); } else { this.$refs.multipleTable.clearSelection(); } }
效果如下,此时可以选中。
然后对代码进行细微修改
toggleSelection(rows) { if (rows) { rows.forEach(row => { // 区别:将内容放在obj对象里面,用于提取需要的字段 const obj = { date: row.date, name: row.name, address: row.address } console.log(obj) this.$refs.multipleTable.toggleRowSelection(obj); }); } else { this.$refs.multipleTable.clearSelection(); } },
这是为什么呢?明明传入的同样是一个对象啊,而且字段名称与数量都是一样的,然而结果却不同?
对比两个打印的内容发现问题:两个打印的字段是有一点点细微的区别的。
然而我个人实力有限,无法找到区别的原理是什么,欢迎留言讨论。
有可能是官方的一个Bug,也可能是官方设计如此,可以去官方git上逛逛:https://github.com/ElemeFE/element/issues