Vuetify VDataTableServer实现点击展开行时自动折叠其他行
Vuetify VDataTableServer 单展开行+用户资料展示解决方案
核心思路
通过控制单个展开项的响应式变量,搭配@toggle-expand事件直接获取点击的用户项,实现点击展开一行时自动折叠其他行,同时加载对应用户的专属资料。
步骤实现
1. 定义响应式变量
在组件脚本部分添加以下变量,分别存储当前展开的用户项和其对应的资料数据:
import { ref } from 'vue'; // 当前展开的用户项 const expandedItem = ref(null); // 当前展开用户的专属资料数据 const currentUserCategories = ref([]);
2. 修改VDataTableServer组件属性
调整组件绑定的属性和事件,替换原有的@update:expanded为@toggle-expand,并通过:expanded控制仅展开当前项:
<VDataTableServer :items="users" item-value="_id" :headers="headers" :loading="loading.table" no-data-text="Nothing found" show-expand :expanded="expandedItem ? [expandedItem._id] : []" @toggle-expand="handleToggleExpand" >
3. 实现展开/折叠处理函数
编写handleToggleExpand函数,处理点击事件:判断点击项是否已展开,切换状态并加载对应用户资料:
// 处理行展开/折叠事件 const handleToggleExpand = async (item) => { // 点击已展开的行,执行折叠操作 if (expandedItem.value === item) { expandedItem.value = null; currentUserCategories.value = []; return; } // 切换到新行,展开并加载用户资料 expandedItem.value = item; // 替换为你的实际接口调用,传入用户_id获取专属资料 try { // 示例:fetchUserCategories是你的接口请求函数 const response = await fetchUserCategories(item._id); currentUserCategories.value = response.data; } catch (error) { console.error('加载用户资料失败:', error); currentUserCategories.value = []; } };
4. 更新展开行模板
将展开行中循环的categories替换为currentUserCategories,确保仅展示当前展开用户的资料:
<template #expanded-row="{ columns }"> <tr :colspan="columns.length"> <td :colspan="columns.length"> <VRow style="padding-top: 1rem; padding-bottom: 1rem"> <VCol v-for="category in currentUserCategories" :key="category.interestName || category._id" cols="12" lg="4" > <VCard :title="category?.interestName" style="background-color: #020b15; border-radius: 1rem" > <template #append> <div class="d-flex gap-1 flex-wrap"> {{ category?.count || 0 }} </div> </template> </VCard> </VCol> </VRow> </td> </tr> </template>
原方法未达预期的原因
- 原
@update:expanded返回的是所有展开项的数组,无法直接定位最后点击的项,容易导致资料展示混乱; - 未通过
:expanded属性主动控制展开项集合,默认允许多行同时展开,不符合单开需求; - 全局的
categories变量会被所有展开行共享,导致所有展开区域展示相同数据。
内容的提问来源于stack exchange,提问作者notCan
相关产品推荐
相关产品推荐

