Element-ui中 表格(Table)组件中 toggleRowSelection 方法设置默认多选项 无法选中解决思路

简介: Element-ui中 表格(Table)组件中 toggleRowSelection 方法设置默认多选项 无法选中解决思路

问题:

Element-ui中,表格(Table)的 toggleRowSelection 方法无法默认选中的情况。

需求:对将设置为选中的内容进行部分修改,如:默认选中的内容必须得通过接口或者其他方式来获取,然后再默认选中。

2020062310470442.png

官方代码:

<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>

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

2020062310470442.png

从图中看,确实可进行默认选中;

默认选中的内容得通过接口或者其他方式获取,然后再默认选中。示例代码如下:

<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>

理论上,上面的内容应该能让表格中的最一列进行选中,然而现实是不行的。

2020062310470442.png

从上面可以看出,首部有选择效果,但却未选中相对应的内容。

解决方法:

从列表(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();
   }
}

效果如下,此时可以选中。

2020062310470442.png

然后对代码进行细微修改

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();
  }
},

2020062310470442.png

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

对比两个打印的内容发现问题:两个打印的字段是有一点点细微的区别的。

然而我个人实力有限,无法找到区别的原理是什么,欢迎留言讨论。

有可能是官方的一个Bug,也可能是官方设计如此,可以去官方git上逛逛:https://github.com/ElemeFE/element/issues


相关文章
|
13天前
|
存储 开发框架 JavaScript
深入探讨Flutter中动态UI构建的原理、方法以及数据驱动视图的实现技巧
【6月更文挑战第11天】Flutter是高效的跨平台移动开发框架,以其热重载、高性能渲染和丰富组件库著称。本文探讨了Flutter中动态UI构建原理与数据驱动视图的实现。动态UI基于Widget树模型,状态变化触发UI更新。状态管理是关键,Flutter提供StatefulWidget、Provider、Redux等方式。使用ListView等可滚动组件和StreamBuilder等流式组件实现数据驱动视图的自动更新。响应式布局确保UI在不同设备上的适应性。Flutter为开发者构建动态、用户友好的界面提供了强大支持。
29 2
|
1月前
|
Android开发 算法 架构师
android的基础ui组件,这些知识点你会吗
android的基础ui组件,这些知识点你会吗
android的基础ui组件,这些知识点你会吗
|
1月前
|
Android开发 缓存 双11
android的基础ui组件,Android开发社招面试经验
android的基础ui组件,Android开发社招面试经验
android的基础ui组件,Android开发社招面试经验
|
17天前
|
XML Android开发 数据格式
【Android UI】中间对齐UI组件
【Android UI】中间对齐UI组件
11 1
|
20天前
|
开发框架 JavaScript 前端开发
微软官方开源免费的Blazor UI组件库 - Fluent UI Blazor
微软官方开源免费的Blazor UI组件库 - Fluent UI Blazor
|
1月前
Vue3+Vite+Pinia+Naive后台管理系统搭建之四:Naive UI 组件库的安装和使用
Vue3+Vite+Pinia+Naive后台管理系统搭建之四:Naive UI 组件库的安装和使用
38 1
|
1月前
|
前端开发 搜索推荐 UED
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
【4月更文挑战第30天】探索Flutter的高级UI组件,如`TabBar`、`Drawer`、`BottomSheet`,提升应用体验和美观度。使用高级组件能节省开发时间,提供内置交互逻辑和优秀视觉效果。示例代码展示了如何实现底部导航栏、侧边导航和底部弹出菜单。同时,自定义组件允许个性化设计和功能扩展,但也带来性能优化和维护挑战。参考Flutter官方文档和教程,深入学习并有效利用这些组件。
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
|
1月前
|
前端开发 JavaScript UED
前端UI组件
前端UI组件
33 0
|
1月前
|
前端开发 搜索推荐 开发者
SAP UI5 sap.m.Column 控件的 minScreenWidth 属性介绍
SAP UI5 sap.m.Column 控件的 minScreenWidth 属性介绍
|
1月前
|
JavaScript 前端开发 开发者
SAP UI5 控件 sap.m.ListBase 的 inset 属性的作用介绍
SAP UI5 控件 sap.m.ListBase 的 inset 属性的作用介绍