Appearance
Tree 树形导航
AuTree 用于紧凑的层级导航。组件内部使用固定行高虚拟列表,并提供默认的选中、悬停、折叠和空状态外观。
基础用法
items 接收已展开为可见行的节点数组;折叠状态由业务侧维护,并在 toggle 事件后重新计算可见节点。下方示例包含三级节点,开关可切换 collapsible,对比普通多级列表与可折叠树的显示效果。
文档导航
包含三级节点;切换折叠模式后,可使用折叠按钮和左右方向键展开、收起各级分组。
当前选择:介绍
vue
<template>
<div class="tree-demo">
<div class="tree-demo__controls">
<AuSwitch
v-model="collapsible"
active-text="开启折叠"
inactive-text="关闭折叠"
aria-label="切换树形导航折叠模式"
/>
</div>
<div class="tree-demo__tree">
<AuTree
:items="visibleItems"
:selected-key="selectedKey"
item-key="id"
label-key="title"
:collapsible="collapsible"
aria-label="文档目录"
@select="selectedKey = $event.id"
@toggle="toggleItem"
/>
</div>
<p class="tree-demo__result">当前选择:{{ selectedItem?.title ?? '未选择' }}</p>
</div>
</template>
<script setup>
import { computed, ref } from 'vue';
import { AuSwitch, AuTree } from 'aurora-plus';
const selectedKey = ref('introduction');
const collapsedKeys = ref(new Set());
const collapsible = ref(true);
const treeItems = [
{
id: 'getting-started',
title: '开始使用',
children: [
{ id: 'introduction', title: '介绍' },
{ id: 'installation', title: '安装' },
{ id: 'quick-start', title: '快速开始' },
],
},
{
id: 'components',
title: '组件',
children: [
{ id: 'button', title: 'Button 按钮' },
{
id: 'navigation',
title: '导航组件',
children: [
{ id: 'tree', title: 'Tree 树形导航' },
{ id: 'virtual-list', title: 'VirtualList 虚拟列表' },
],
},
],
},
{ id: 'changelog', title: '更新日志' },
];
const visibleItems = computed(() => flattenVisibleItems(treeItems));
const selectedItem = computed(() =>
visibleItems.value.find((item) => item.id === selectedKey.value)
);
function flattenVisibleItems(items, displayDepth = 0) {
return items.flatMap((item) => {
const hasChildren = Array.isArray(item.children) && item.children.length > 0;
const isCollapsed = collapsible.value && collapsedKeys.value.has(item.id);
const row = {
id: item.id,
title: item.title,
displayDepth,
hasChildren,
isCollapsed,
};
if (!hasChildren || isCollapsed) return [row];
return [row, ...flattenVisibleItems(item.children, displayDepth + 1)];
});
}
function toggleItem(item) {
const nextCollapsedKeys = new Set(collapsedKeys.value);
if (nextCollapsedKeys.has(item.id)) {
nextCollapsedKeys.delete(item.id);
} else {
nextCollapsedKeys.add(item.id);
}
collapsedKeys.value = nextCollapsedKeys;
}
</script>
<style scoped>
.tree-demo__controls {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.tree-demo__tree {
height: 252px;
overflow: hidden;
border: 1px solid var(--au-color-border-lighter);
border-radius: 8px;
}
.tree-demo__result {
margin: 10px 0 0;
color: var(--au-color-text-secondary);
font-size: var(--au-font-size-small);
}
</style>使用建议
- 每个节点需要稳定的唯一 key;可用
itemKey与labelKey映射已有数据字段。 disabledKey指向值为真时不可选择的字段;禁用节点仍可通过独立折叠按钮展开子级。collapsible默认为false;关闭时按普通层级列表显示,不渲染展开/收起控件。- 开启
collapsible后,父节点需提供hasChildren与isCollapsed,并由toggle事件更新折叠状态。 - 组件负责渲染可见行,业务侧负责将嵌套数据转换为带
displayDepth的扁平数组。
Attributes
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
items | 已展开为可见行的树节点数组 | Array | [] |
selectedKey | 当前选中节点 key | string | number | null | null |
itemKey | 节点 key 字段名 | string | id |
labelKey | 节点标题字段名 | string | label |
disabledKey | 节点禁用字段名 | string | disabled |
itemHeight | 固定行高 | number | 28 |
overscan | 视口外预渲染行数 | number | 8 |
baseIndent | 根节点起始缩进 | number | 10 |
indent | 每层缩进距离 | number | 16 |
collapsible | 是否启用折叠模式;开启后显示节点折叠控件 | boolean | false |
emptyText | 空状态文本 | string | 暂无数据 |
ariaLabel | 树导航无障碍名称 | string | 树形导航 |
Events
| 事件名 | 说明 | 参数 |
|---|---|---|
select | 选择节点 | (item) |
toggle | 请求切换节点展开状态 | (item) |
Exposes
| 属性或方法 | 说明 |
|---|---|
scrollToTop() | 滚动到顶部 |
scrollToIndex(index, align?) | 滚动到指定节点 |