vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > elementui[el-table]toggleRowSelection默认多选事件无法选中

elementui[el-table]toggleRowSelection默认多选事件无法选中问题

作者:墨水白云

这篇文章主要介绍了elementui[el-table]toggleRowSelection默认多选事件无法选中问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

问题

今天发现了一个elment el-table toggleRowSelection事件无法默认选中的情况,

我的需求可能需要对内容进行一部分修改,比如:我默认选中的内容必须得通过接口或者其他方式来获取,然后再默认选中

解决方式

// 这里通过循环选中列表multipleSelection,然后从所有列表tableData中找到需要选中的项来帮助选中,直接使用选中列表来设置可能会出错
toggleSelection(rows) {
  // multipleSelection是一个选中数据列表
  // tableData 是所有的数据列表
  this.multipleSelection.forEach(row => {
    // 不能自己自定义对象来设置选中(原因如下分析),那我可以从列表中找到需要选中的那个对象,然后把它拿过来作为选中的项就可以了
  	this.$refs.multipleTable.toggleRowSelection(this.tableData.find(item=>{
      return row.name == item.name;  // 注意这里寻找的字段要唯一,示例仅参考
    }),true);
  });
}

另外一种无法选中的方式

原因可能在于vue组件和表格的渲染顺序问题。如:代码执行的时候页面渲染还未完成。(表格放在dialog之类的弹出框里面) 

解决方式:

在循环的外层加个$nextTick即可

this.$nextTick(()=>{
	this.multipleSelection.forEach(row => {
	    console.log(row); // 这里仅仅加了个打印操作
	    this.$refs.multipleTable.toggleRowSelection(this.tableData.find(item=>{
      		return row.name == item.name;  // 注意这里寻找的字段要唯一,示例仅参考
   		}),true);
	});
})

分析

自己研究了一下elementUI el-table 的多选内容:

官方代码如图:

<template>
  <el-table
    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>
</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>

上面的代码就是官方代码、使用效果如下:

从图中看,确实可以进行行数的默认选中

(以上都是官方内容);

然而我的需求可能需要对内容进行一部分修改,比如:我默认选中的内容必须得通过接口或者其他方式来获取,然后再默认选中

示例如下:

// 这个假如是通过接口或者其他形势获得的某个选中行内容
// 注意这里多了几个字段
multipleSelection: [
  {
    date: "2016-05-07",
    name: "王小虎",
    address: "上海市普陀区金沙江路 1518 弄",
    description: '这里是描述',
    type: '类型',
    id: 'aaaaa111111'
  }
]
// 因此我的选中代码必须得改成如下:
toggleSelection() {
  // 循环multipleSelection,然后将内容提取出我要的字段
  // 使其于table表行字段对应
  this.multipleSelection.forEach(row => {
    let arr = {
      date: row.date,
      name: row.name,
      address: row.address
    };
    // 设置默认选中列
    this.$refs.multipleTable.toggleRowSelection(arr,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 => {
       // 区别仅仅是将内容放在arr对象里面了,用于提取需要的字段
       let arr = {
       		date: row.date,
      		name: row.name,
      		address: row.address
       }
       console.log(arr); // 打印操作
       this.$refs.multipleTable.toggleRowSelection(arr);
     });
   } else {
     this.$refs.multipleTable.clearSelection();
   }
}

效果如下:首部选中,其他行却没选中

这是为什么呢?明明传入的同样是一个对象啊,而且字段名称与数量都是一样的,然而结果却不同?

对比两个打印的内容发现问题:两个打印的字段是有一点点细微的区别的。然而我个人实力有限,无法找到区别的原理是什么!哎!

有可能是官方的一个Bug,也可能是官方设计如此,可以去官方git上逛逛:

https://github.com/ElemeFE/element/issues

但是问题却也是可以解决的(在最上面)。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文