数据结构
const data = ref([
{
id: 1,
parent_id: 0,
name: '系统管理',
children: [
{
id: 2,
parent_id: 1,
name: '用户管理',
children: []
},
{
id: 3,
parent_id: 1,
name: '角色管理',
children: null // 注意:null会被自动转换为[]
}
]
}
]);
配置表
子节点配置
const treeConfig: EnhancedTableProps['tree'] = reactive({
childrenKey: 'children', // 指定子节点字段名
treeNodeColumnIndex: 2, // 展开子节点的按钮放在第2列
indent: 50, // 节点缩进像素
expandTreeNodeOnClick: true, // 点击节点时展开/折叠
});
treeNodeColumnIndex: 红框
indent:绿框的宽度
表格属性
<t-enhanced-table
ref="tableRef"
v-model:expandedTreeNodes="expandedTreeNodes" //子节点
row-key="id"
:data="data" //绑定数据
:columns="columns" //表头设置与字段绑定
:tree="treeConfig" //
:tree-expand-and-fold-icon="treeExpandIcon" //修改按钮图标
></t-enhanced-table>
例子
<template>
<div>
<div>
<t-button theme="default" style="margin-left: 16px" @click="resetData">重置/更新数据</t-button>
<t-button theme="default" style="margin-left: 16px" @click="onExpandAllToggle">{{ expandAll ? '收起全部' : '展开全部' }}</t-button>
</div>
<br />
<!-- 树形结构 EnhancedTable -->
<t-enhanced-table
ref="tableRef"
v-model:expandedTreeNodes="expandedTreeNodes"
row-key="id"
:data="data"
:columns="columns"
:tree="treeConfig"
:tree-expand-and-fold-icon="treeExpandIcon"
></t-enhanced-table>
</div>
</template>
<script lang="tsx" setup>
import { ref, reactive, onMounted } from 'vue';
import {
EnhancedTable as TEnhancedTable,
MessagePlugin,
EnhancedTableProps,
EnhancedTableInstanceFunctions,
ButtonProps,
TableRowData,
} from 'tdesign-vue-next';
import { ChevronRightIcon, ChevronDownIcon } from 'tdesign-icons-vue-next';
import { getMenuList } from '@/api/system/menu';
const treeExpandIcon: EnhancedTableProps['treeExpandAndFoldIcon'] = (h, { type }) => {
return type === 'expand' ? <ChevronRightIcon /> : <ChevronDownIcon />;
};
// 定义菜单数据结构
interface MenuData {
id: number;
parent_id: number;
path: string;
name: string;
zh_cn: string;
en_us: string;
single: boolean;
hidden: boolean;
frame_blank: boolean;
children?: MenuData[];
}
const tableRef = ref<EnhancedTableInstanceFunctions>(null);
const data = ref<MenuData[]>([]);
const loading = ref(false);
// 树形配置
const expandedTreeNodes = ref<EnhancedTableProps['expandedTreeNodes']>([]);
const treeConfig: EnhancedTableProps['tree'] = reactive({
childrenKey: 'children',
treeNodeColumnIndex: 2,
indent: 25,
expandTreeNodeOnClick: true,
});
// 从接口获取菜单数据
const fetchMenuData = async () => {
loading.value = true;
try {
const response = await getMenuList();
// 直接使用接口返回的树形结构数据
data.value = response || [];
MessagePlugin.success('菜单数据加载成功');
} catch (error) {
MessagePlugin.error('菜单数据加载失败');
console.error('获取菜单数据失败:', error);
} finally {
loading.value = false;
}
};
// 重置数据和展开节点
const resetData: ButtonProps['onClick'] = () => {
fetchMenuData();
expandedTreeNodes.value = [];
};
const onEditClick = (row: TableRowData) => {
const newData = {
...row,
zh_cn: `修改后的-${row.zh_cn}`,
};
tableRef.value.setData(row.id, newData);
MessagePlugin.success('菜单数据已更新');
};
const onDeleteConfirm = (row: TableRowData) => {
tableRef.value.remove(row.id);
MessagePlugin.success('删除成功');
};
const onLookUp = (row: TableRowData) => {
const allRowData = tableRef.value.getData(row.id);
const message = '当前菜单全部数据,包含节点路径、父节点、子节点、是否展开、是否禁用等';
MessagePlugin.success(`打开控制台查看${message}`);
console.log(`${message}:`, allRowData);
};
const columns: EnhancedTableProps['columns'] = [
{
colKey: 'id',
title: 'ID',
ellipsis: true,
width: 80,
},
{
colKey: 'path',
title: '路径',
width: 120,
},
{
colKey: 'name',
title: '名称',
width: 100,
},
{
width: 180,
colKey: 'zh_cn',
title: '中文名称',
ellipsis: true,
},
{
colKey: 'en_us',
title: '英文名称',
width: 120,
},
{
colKey: 'operate',
width: 220,
title: '操作',
cell: (h, { row }) => (
<div class="tdesign-table-demo__table-operations">
<t-link variant="text" hover="color" onClick={() => onEditClick(row)}>
更新
</t-link>
<t-link variant="text" hover="color" onClick={() => onLookUp(row)}>
查看
</t-link>
<t-popconfirm content="确认删除吗" onConfirm={() => onDeleteConfirm(row)}>
<t-link variant="text" hover="color" theme="danger">
删除
</t-link>
</t-popconfirm>
</div>
),
},
];
const expandAll = ref(false);
const onExpandAllToggle: ButtonProps['onClick'] = () => {
expandAll.value = !expandAll.value;
expandAll.value ? tableRef.value.expandAll() : tableRef.value.foldAll();
};
// 组件挂载时加载数据
onMounted(() => {
fetchMenuData();
});
</script>
<style>
.tdesign-table-demo__table-operations .t-link {
padding: 0 8px;
}
</style>