v-data-table使用v-slot:body搭配v-checkbox行选择时全选异常如何解决
自定义复选框与v-data-table默认复选框的差异
- 默认复选框绑定v-data-table内部维护的选中状态映射,基于
item-key配置的唯一标识做选中匹配,仅会保留标识匹配的原有选中项,不受items数组更新时的对象引用变化影响 - 自定义实现的复选框直接将
v-model绑定到selected数组,且默认按对象引用做匹配,当items数组变更生成新的对象引用时,v-model的数组绑定逻辑会误判所有新对象为待选中项,最终触发全选异常
保留body插槽的修复方案
有两种可行实现方式:
方案1:直接控制选中状态
不用v-model绑定整个数组,改为手动控制选中逻辑,按item-key做匹配判断,避免对象引用影响:
<v-data-table v-model="selected" :headers="headers" :items="desserts" item-key="name" show-select dense hide-default-footer class="elevation-1" > <template v-slot:body="{ items }"> <tbody> <tr v-for="d in items" :key="d.name"> <td> <v-checkbox :input-value="selected.some(item => item.name === d.name)" @change="isChecked => { if (isChecked) selected.push(d) else selected = selected.filter(item => item.name !== d.name) }" style="margin:0px;padding:0px" hide-details ></v-checkbox> </td> <td>{{ d.name }}</td> <td>{{ d.calories }}</td> </tr> </tbody> </template> </v-data-table>
方案2:绑定唯一标识而非完整对象
将选中数组改为存储item-key对应的唯一值,而非完整对象,从根源避免引用匹配的问题,性能更优:
<!-- 脚本部分需将原来的selected数组改为selectedKeys,存储选中的name值 --> <v-data-table :headers="headers" :items="desserts" item-key="name" show-select dense hide-default-footer class="elevation-1" > <template v-slot:body="{ items }"> <tbody> <tr v-for="d in items" :key="d.name"> <td> <v-checkbox v-model="selectedKeys" :value="d.name" style="margin:0px;padding:0px" hide-details ></v-checkbox> </td> <td>{{ d.name }}</td> <td>{{ d.calories }}</td> </tr> </tbody> </template> </v-data-table>
额外注意:如果需要保留表头自带的全选功能,需要额外自定义
header.data-table-select插槽同步全选逻辑,原生全选控件不会自动和自定义的行复选框联动。
内容的提问来源于stack exchange,提问作者Alexandre Boulay
相关产品推荐
相关产品推荐

