Vue多选框保留勾选数据实现方式
作者:慕白Lee
背景
封装组件的时候遇到一个场景:
查询两个接口数据得到两个分组集合, 需要动态切换分组选中状态,
刷新最新的并集,并且可以保留勾选状态+模糊搜索, 两个分组会存在相同元素的可能.
- 第一阶段:初始化页面的时候请求接口并保存初始分组数据, 一开始是定义了两个集合用来保存:data的数据, 集合数据动态切换变化的时候直接获取最新的, 但是缺点是不能保存勾选状态.
- 第二阶段:发现只能操作原:data的数据, 所谓的checked再往回赋值根本没用. 缺点是数据操作和列表数据模糊查询不能实现.
- 第三阶段:发现了reserve-selection这个东东, 近乎完美解决问题
总结:遇到问题先别急着造轮子, 大概率有对应的功能标签了, 一般的业务根本触及不到vue的设计缺陷的...
问题分析与解决
第一阶段:初始化与数据同步
在页面初始化时,通过请求接口保存两个分组的初始数据。
定义两个集合来保存数据,并在集合数据变化时直接获取最新的数据。
这个方法的缺点是无法保存用户的勾选状态。
第二阶段:直接操作原始数据
后来发现,必须直接操作原始的 data
数据集合。
尝试将勾选状态作为属性赋值回数据集合是无效的,同时也无法实现数据操作和列表模糊查询的需求。
第三阶段:引入reserve-selection
最终,使用 reserve-selection
属性解决了勾选状态保留的问题,这表明在遇到问题时应该首先考虑框架或库本身是否提供了解决方案,而不是急于自己编写解决方案。
保存数据勾选状态reserve-selection
demo简化演示
<el-table ref="table" :row-key="rowKey" :data="tableData" @selection-change="selectionChange" max-height="666px"> <el-table-column type="selection" label="全部" width="55" align="center" :reserve-selection="true" /> <el-table-column label="姓名" align="left" prop="name" /> <el-table-column label="手机号" align="left" prop="phone"/> </el-table>
methods: { rowKey(row) { //row-key就是要指定一个key标识这一行的数据,保证唯一即可 return row.id; }, // 列表选择,val选中的表格行数据 selectionChange(val) { console.log(val) }, //清除表格所有的选中项 clearSelect(){ //方法1 this.$refs["table"].clearSelection(); //方法2 this.$refs.buyerTable.clearSelection(); }, },
reserve-selection完整使用小例
在Vue.js中,`reserve-selection` 是一个用于 `<el-table>` 组件(基于 Element UI)的属性,用于在表格分页时保留已选中的行。
当 `reserve-selection` 属性设置为 `true` 时,表格在分页时会保留已选中的行,而不会清除选中状态。这样,在用户切换分页时,之前选中的行将保持选中状态。
下面是一个示例,演示了如何在 `<el-table>` 组件中使用 `reserve-selection` 属性:
<template> <el-table :data="tableData" :reserve-selection="true" @selection-change="handleSelectionChange" > <el-table-column type="selection"></el-table-column> <el-table-column prop="name" label="Name"></el-table-column> <el-table-column prop="age" label="Age"></el-table-column> </el-table> </template> <script> export default { data() { return { tableData: [ { name: 'John', age: 25 }, { name: 'Jane', age: 30 }, { name: 'Bob', age: 35 }, ], selectedRows: [], }; }, methods: { handleSelectionChange(selection) { this.selectedRows = selection; }, }, }; </script>
在上面的示例中,`reserve-selection` 属性设置为 `true`,并且通过 `@selection-change` 事件监听器,将选中的行存储在 `selectedRows` 数组中。
当用户在表格中选择行时,`handleSelectionChange` 方法会被调用,将选中的行存储在 `selectedRows` 数组中。即使用户切换分页,已选中的行也会保持选中状态。
请注意:
- reserve-selection属性仅适用于基于 Element UI 的<el-table>组件。
- 如果您使用的是其他表格组件或自定义的表格组件,可能没有类似的属性或功能。
- 在这种情况下,您可能需要自行实现保留选中状态的逻辑。
清除某些选中项
基于上述理解, 还要实现选中项清空的功能
demo代码
for (let i = 0; i < this.selections.length; i++) { if (true) { this.$refs.table.toggleRowSelection(this.selections[i]); i--; } }
相关知识点
this.$refs.table.toggleRowSelection
是在Vue.js中使用$refs
访问组件实例的特殊语法。它用于在Vue组件中的方法中调用子组件的方法或访问子组件的属性。
假设您有一个名为 table
的子组件,并且在父组件中使用了 ref="table"
来引用该子组件。那么,通过 this.$refs.table
,您可以访问到子组件的实例,从而调用子组件的方法或访问子组件的属性。
toggleRowSelection
是一个假设 table
子组件中有一个名为 toggleRowSelection
的方法的示例。它的作用是切换表格中某一行的选中状态。
例如,假设您的 table
子组件具有以下方法:
methods: { toggleRowSelection(row) { // 在这里实现切换行选中状态的逻辑 } }
然后,在父组件中的某个方法中,您可以使用 this.$refs.table.toggleRowSelection(row)
来调用子组件的 toggleRowSelection
方法,并传递相应的行数据作为参数。
这样,您可以在父组件中控制子组件的行选中状态。
请注意:
- 使用
$refs
访问子组件的实例是一种直接操作子组件的方法,但也可能导致父子组件之间的耦合增加。 - 在设计和开发过程中,请谨慎使用
$refs
,并确保遵循Vue.js的组件通信原则。
细节优化
- 清除某行数据时, 集合的长度会实时变化, 如果按照原有索引去删除就会少删.
- 所以, 正序删的时候, 每删除一个就要索引-1
- 反序删直接删就行
扩展方向思考
- 状态同步:如果两个分组存在相同的元素,考虑使用一个映射表(例如使用 JavaScript 对象)来同步这些元素的勾选状态。
- 模糊搜索:可以在组件内部实现一个搜索方法,该方法能够在用户输入搜索关键字时过滤数据并更新表格。
- 性能考虑:如果数据集非常大,考虑使用虚拟滚动或分页来提高性能。
- 用户体验:提供清晰的用户反馈,例如在切换分组或执行搜索时显示加载指示器。
通过以上的优化,可以确保组件在处理复杂数据和用户交互时保持高性能和良好的用户体验。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。