跳转到内容

tree

数据展示组件。三层同源:无头内核给出解剖与状态机,Vue 组件与自定义元素只是它的两层外壳,行为完全一致。

示例

基础用法

collection 是层级元信息的唯一事实源,标记只管长相;缩进由子层容器自己顶着

项目文件
src
main.ts
README.md

多选

selectionMode 默认 single,改成 multiple 后点击与确认键都变成切换,选中集合形状不变仍是数组

投放城市
华东
上海
杭州
南京
华北
北京
天津
选中:hz

受控

传了 expandedValue / selectedValue 就由宿主说了算,组件只发事件不落内部值,宿主写回它才动

文档目录
接口
鉴权
用户
展开:api · 选中:(无)

点行不展开与禁用节点

expandOnClick 关掉后只有箭头与左右方向键能改展开态;禁用节点仍可聚焦,只是确认键不认它

构建产物
build
vite.config.ts
pnpm-lock.yaml(禁用)
README.md

关键词过滤

collection 换一份树就换一棵:标记跟着数据用 v-for 渲,过滤剩下的分支顺手全展开

投放城市
华东
上海
杭州
南京

异步加载子节点

展开那一刻才去要数据:先摆一行禁用的占位,取回来就地换掉,收起再展开不重复请求

组织架构

前缀与行尾

行里放什么由标记说了算:文字前塞图标、文字后塞操作,方向指示也可以挪到行尾去

工作区
src
index.ts
app.vue
(还没动过)

只让叶子进选中集合

选中受控就由宿主定夺:分支的值直接不写回,点目录只剩展开收起这一个效果

要提交的文件
src
index.ts
app.vue
已选:(无)

级联勾选

selection-mode="multiple" 加 cascade 内建父子传导:点分支整枝勾上、子全勾父勾、部分勾中半选;勾选框是行里的一段标记,态从插槽作用域取

投放城市
华东
上海
杭州
南京
华北
北京
天津

选中值(默认只收叶):hz

拖放换父

树从不拥有数据:把 draggable 与拖放监听补在节点上,落点判定与数组搬运都在宿主这边,改完 collection 树自己重推层级

邮箱目录
收件箱2
报价单.pdf
周报.md
归档1
去年总结.docx
回收站0
把文件拖到别的目录上放开

产物

自定义元素<xh-tree>
Vue 组件XhTreeBranch XhTreeBranchContent XhTreeBranchControl XhTreeBranchIndicator XhTreeBranchText XhTreeBranchTrigger XhTreeItem XhTreeItemIndicator XhTreeItemText XhTreeLabel XhTreeRoot XhTreeTree
组合式函数useTree
状态机treeMachine
皮肤@xihan-ui/styles/tree.css

解剖

部件名即 data-part 属性值,也是皮肤的选择器。加粗的是必备部件,不渲染它组件不工作(Web Components 适配器会在诊断通道上报 wc.missing-part)。

data-scope="tree"root · label · tree · item · item-indicator · item-text · branch · branch-control · branch-trigger · branch-indicator · branch-text · branch-content

Props

属性类型必填说明
collectionTreeNode[]树数据,层级元信息的唯一事实源。缺省为空树。
expandedValuestring[]展开集合。给定即受控:cell 直读 prop,写只发 onExpandedChange 不落内部值。
defaultExpandedValuestring[]
selectedValuestring[]选中集合。给定即受控,语义同上。
defaultSelectedValuestring[]
selectionModeTreeSelectionMode默认 single。
cascadebooleanmultiple 下父子级联勾选:点分支整枝传导、子全勾父勾、部分勾中半选, 禁用子树整棵冻结。默认 false(朴素切换);single 下无效。
checkedStrategyCascadeStrategy级联下对外值的收敛策略,默认 child(只收叶);parent = 最高整枝,all = 全部勾中节点。
expandOnClickboolean点分支行是否顺带展开/收起,默认 true。关掉后只有 branch-trigger 与左右方向键能改展开态。
disabledboolean整棵树禁用:所有节点转 aria-disabled,键盘与点击都不再改展开/选中。
loopboolean上下键走到首尾是否回绕,默认 false。
typeaheadboolean连打检索,默认开。关掉后可打印字符一律放行给页面。
dirDirection文字方向,默认 ltr;只对调左右方向键的「展开/收起」语义。
onExpandedChange(details: TreeExpandedChangeDetails) => void
onSelectionChange(details: TreeSelectionChangeDetails) => void

状态机

状态idle

事件EXPANDED.SET · BRANCH.EXPAND · BRANCH.COLLAPSE · BRANCH.TOGGLE · SELECTED.SET · NODE.SELECT · NODE.FOCUS · TREE.BLUR

connect API

useTree 产出的对象。getXxxProps() 铺到对应部件的宿主元素上,其余是可读状态与操作入口。

成员类型说明
collectionreadonly TreeNode[]作者给的原始树数据。
visibleNodesreadonly TreeVisibleNode[]当前可见行序列(收起分支的子树不在其中)。 方向键、Home/End 与连打检索都在它上面走,不是在原始树上走。
expandedValuestring[]
selectedValuestring[]
focusedValuestring | null焦点锚点;焦点不在树内、或它已被收起而不可见时为 null。
selectionModeTreeSelectionMode
disabledboolean
isExpanded(value: string) => boolean
isSelected(value: string) => boolean
isIndeterminate(value: string) => boolean级联模式下该分支是否半选(有效叶后代有勾有不勾);非级联恒 false。
setExpandedValue(next: string[]) => void
setSelectedValue(next: string[]) => void
expand(value: string) => void
collapse(value: string) => void
select(value: string) => void单选替换、复选切换,与点击同一语义。
getRootProps() => T['element']
getLabelProps() => T['element']
getTreeProps() => T['element']
getItemProps(props: TreeNodeProps) => T['element']
getItemTextProps(props: TreeNodeProps) => T['element']
getItemIndicatorProps(props: TreeNodeProps) => T['element']
getBranchProps(props: TreeNodeProps) => T['element']
getBranchControlProps(props: TreeNodeProps) => T['element']
getBranchTriggerProps(props: TreeNodeProps) => T['element']
getBranchIndicatorProps(props: TreeNodeProps) => T['element']
getBranchTextProps(props: TreeNodeProps) => T['element']
getBranchContentProps(props: TreeNodeProps) => T['element']

键盘

规格出处:W3C APG

按键生效条件行为
Tab / Shift+Tabfocus outside the tree整棵树只占一个 Tab 位:焦点进入锚点节点,无锚点时先落容器再由它转投
ArrowDownfocus in tree焦点移到下一个可见行(禁用行跳过;loop 默认关,末行不回绕)
ArrowUpfocus in tree焦点移到上一个可见行(禁用行跳过;loop 默认关,首行不回绕)
Homefocus in tree焦点移到首个可见行
Endfocus in tree焦点移到末个可见行(展开着的子树也算行)
ArrowRightfocus on branch(dir=rtl 时改由 ArrowLeft 承担)收起的分支就地展开;已展开则把焦点移到首个子节点;叶子上什么都不做且不吞键
ArrowLeftfocus in tree(dir=rtl 时改由 ArrowRight 承担)展开的分支就地收起;收起的分支与叶子则把焦点移到父节点;根层的行什么都不做
Enter / Spacefocus on node, 节点未禁用选中焦点节点(单选替换、复选切换);焦点在分支上且 expandOnClick 未关时顺带切换展开态
*focus in tree展开与焦点行同一父级的全部分支(已展开与禁用的不动);同级没有可展开的分支时不吞这个键
单个可打印字符focus in tree, typeahead 未关连打检索在可见行上按 label 首字母搬焦点,不改选中值,也不展开任何分支

Released under The MIT License