Vue表格标准全选功能实现异常如何优雅解决?
核心问题说明
现有代码的问题在于全选框的被动状态更新(取消单行选中导致全选框变为未选中)和用户主动点击全选框的操作共用了同一套set逻辑,没有做区分,导致被动更新时误清空所有选中项。
方案1:添加半选状态(推荐,符合主流交互规范)
这是企业级表格的标准实现,能清晰区分「全选」「部分选中」「未选中」三种状态,从根源避免被动状态更新触发异常逻辑。
修改后完整代码如下:
<template> <table class="MyComponent table"> <thead> <tr> <th width="30px"> <!-- 增加半选状态绑定 --> <b-form-checkbox v-model="allChecked" :indeterminate="isIndeterminate" /> </th> </tr> </thead> <tbody> <tr v-for="(record, index) in records" :key="index"> <td width="30px"> <b-form-checkbox :value="record['id']" v-model="checkedRows" /> </td> </tr> </tbody> </table> </template> <script> export default { name: "MyComponent", components: {}, props: ['config'], data() { return { records: [ {id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6} ], checkedRows: [] } }, computed: { allChecked: { get() { // 全选判断逻辑不变 return this.records.length && this.records.length == this.checkedRows.length }, set(v) { // 主动操作逻辑不变 if(v) { this.checkedRows = this.records.map(item => item.id) } else { this.checkedRows = [] } } }, // 新增半选状态判断:有选中项但未全选时为true isIndeterminate() { return this.checkedRows.length > 0 && this.checkedRows.length < this.records.length } } }; </script>
方案2:最小改动修复,无需半选状态
如果不需要半选交互,只需修改allChecked的set逻辑,区分被动失活和主动操作场景即可,仅需改动几行代码:
allChecked: { get() { return this.records.length == this.checkedRows.length }, set(v) { if(v) { this.checkedRows = this.records.map(item => item.id) } else { // 只有当前是全选状态时,点击取消才清空所有 // 避免取消单行触发的被动失活导致误清空 if (this.checkedRows.length === this.records.length) { this.checkedRows = [] } } } }
内容的提问来源于stack exchange,提问作者RobbeR
相关产品推荐
相关产品推荐

