Vuetify v-data-table分组自定义插槽分页选中状态异常求助
问题解决:Vuetify v-data-table分页后分组标题复选框异常选中及选中状态丢失
问题原因
你当前的实现把分组名直接绑定到复选框的value,但v-data-table的v-model="selected"是用来绑定行数据对象的,分页时组件重新渲染,会把分组名误识别为选中项,同时没有单独维护分组的选中状态,导致切换分页后之前的选中记录丢失。
解决方案
单独维护分组选中状态,将分组复选框与行选中状态解耦,同时实现分组全选/取消的联动逻辑:
修改后的完整代码
<div id="app"> <v-app id="inspire"> <v-data-table v-model="selected" :headers="headers" :items="desserts" item-key="name" @click:row="handleClick" class="elevation-1" group-by='class' :items-per-page="4" > <template v-slot:group.header="{items, group}"> <th colspan="6"> <v-checkbox v-model="groupSelected" :value="group" @change="toggleGroupSelection(group)" > <template v-slot:label> {{ group }} </template> </v-checkbox> </th> </template> </v-data-table> </v-app> </div> <script> new Vue({ el: '#app', vuetify: new Vuetify(), methods:{ handleClick(value) { console.log(value) // 行选中时同步分组复选框状态 this.syncGroupCheckbox(value.class) }, toggleGroupSelection(groupName) { // 获取当前分组下的所有行 const groupItems = this.desserts.filter(item => item.class === groupName) if (this.groupSelected.includes(groupName)) { // 勾选分组:添加该组所有行到选中列表 this.selected = [...new Set([...this.selected, ...groupItems])] } else { // 取消分组:移除该组所有行 this.selected = this.selected.filter(item => item.class !== groupName) } }, syncGroupCheckbox(groupName) { // 检查该分组下所有行是否都被选中 const groupItems = this.desserts.filter(item => item.class === groupName) const allSelected = groupItems.every(item => this.selected.includes(item)) const groupIndex = this.groupSelected.indexOf(groupName) if (allSelected && groupIndex === -1) { this.groupSelected.push(groupName) } else if (!allSelected && groupIndex !== -1) { this.groupSelected.splice(groupIndex, 1) } } }, data () { return { singleSelect: false, selected: [], // 单独维护分组选中状态 groupSelected: [], headers: [ { text: 'Dessert (100g serving)', align: 'start', sortable: false, value: 'name', }, { text: 'Calories', value: 'calories' }, { text: 'Fat (g)', value: 'fat' }, { text: 'Carbs (g)', value: 'carbs' }, { text: 'Protein (g)', value: 'protein' }, { text: 'Iron (%)', value: 'iron' }, ], desserts: [ { name: 'Frozen Yogurt', calories: 159, fat: 6.0, carbs: 24, protein: 4.0, iron: '1%', class: 'w1' }, { name: 'Ice cream sandwich', calories: 237, fat: 9.0, carbs: 37, protein: 4.3, iron: '1%', class: 'w2' }, { name: 'Eclair', calories: 262, fat: 16.0, carbs: 23, protein: 6.0, iron: '7%', class: 'w2' }, { name: 'Eclair2', calories: 262, fat: 16.0, carbs: 23, protein: 6.0, iron: '7%', class: 'w2' }, { name: 'Eclair3', calories: 262, fat: 16.0, carbs: 23, protein: 6.0, iron: '7%', class: 'w3' },{ name: 'Eclair4', calories: 262, fat: 16.0, carbs: 23, protein: 6.0, iron: '7%', class: 'w3' }, ], } }, }) </script>
关键改动说明
- 新增
groupSelected数组,专门存储选中的分组名,与行选中的selected数组解耦,避免分页时的状态混淆。 - 分组头的复选框使用
v-model="groupSelected"绑定分组选中状态,同时通过@change事件触发分组全选/取消逻辑。 - 添加
toggleGroupSelection方法,实现点击分组复选框时,自动选中/取消该分组下的所有行。 - 添加
syncGroupCheckbox方法,当单独选中行时,同步更新对应分组的复选框状态(所有行都选中时自动勾选分组框,否则取消)。
这样修改后,分页时分组选中状态不会丢失,也不会出现分组标题被错误选中的问题,同时保持了分组与行选中状态的联动。
内容的提问来源于stack exchange,提问作者MMzztx
相关产品推荐
相关产品推荐

