@1samare/node-tree
高性能双向树布局组件,附带 Vue 2 适配层与纯布局 core。
安装
npm install @1samare/node-tree vue@^2.7
快速开始
import Vue from 'vue'
import NodeTree from '@1samare/node-tree/vue2'
import '@1samare/node-tree/style.css'
Vue.use(NodeTree)
<node-tree :data="treeData" layout-direction="horizontal" />
引入方式
| 路径 |
说明 |
@1samare/node-tree |
默认导出(core + Vue2 组件) |
@1samare/node-tree/vue2 |
Vue 2 插件与 NodeTree 组件 |
@1samare/node-tree/core |
纯布局算法(layoutForest、insertTreeNode 等) |
@1samare/node-tree/style.css |
组件样式 |
Props
| Prop |
类型 |
默认值 |
说明 |
data |
TreeNodeData | TreeNodeData[] |
必填 |
树数据,支持单根或多根(forest) |
layoutDirection |
'horizontal' | 'vertical' |
'horizontal' |
布局方向:horizontal 左右,vertical 上下 |
nodeWidth |
number |
320 |
节点宽度 |
nodeMinHeight |
number |
72 |
节点最小高度 |
horizontalGap |
number |
96 |
层间主轴间距 |
verticalGap |
number |
24 |
兄弟节点最小交叉轴间距(最小间隙) |
rootGap |
number |
80 |
多根树之间的最小间距 |
padding |
number |
48 |
画布内边距 |
scale |
number |
1 |
当前缩放比例,支持 .sync / update:scale |
minScale |
number |
0.1 |
最小缩放 |
maxScale |
number |
2 |
最大缩放 |
scaleStep |
number |
0.1 |
缩放步进 |
zoomable |
boolean |
true |
是否允许缩放;为 false 时隐藏缩放 UI、锁定 scale=1 |
showToolbar |
boolean |
true |
是否显示工具栏(无缩略图时) |
showMiniMap |
boolean |
true |
是否显示缩略图(小地图) |
draggable |
boolean |
true |
是否允许拖拽平移画布 |
allowAdd |
boolean |
true |
是否在连接器上显示「添加子节点」按钮 |
createChildNode |
(parent, side) => TreeNodeData | undefined |
— |
点击添加时自动生成子节点数据 |
loadChildren |
(node) => Promise<TreeNodeData[]> |
— |
异步加载子节点 |
onAddChild |
(node, side) => void |
— |
已废弃,请使用 addNode 或 add-node-request |
collapsedIds |
string[] |
[] |
收起状态 key 列表 |
defaultCollapseChildren |
boolean |
true |
初始是否收起已有子节点 |
virtual |
boolean |
true |
是否启用视口虚拟渲染 |
overscan |
number |
240 |
虚拟渲染 overscan 像素 |
initialCenter |
boolean |
true |
挂载后是否自动居中根节点 |
centerDuration |
number |
180 |
居中动画时长(ms) |
树数据字段
interface TreeNodeData {
id: string
title: string
owner?: string
progress?: number
status?: 'normal' | 'risk' | 'delayed' | 'unset'
hasChild?: boolean
leftChildren?: TreeNodeData[] // horizontal 左侧 / vertical 上方
rightChildren?: TreeNodeData[] // horizontal 右侧 / vertical 下方
children?: TreeNodeData[] // rightChildren 的兼容别名
}
Methods(通过 ref 调用)
| 方法 |
说明 |
zoomIn() |
放大一步(受 zoomable 控制) |
zoomOut() |
缩小一步(受 zoomable 控制) |
setScale(scale) |
设置缩放比例 |
resetView() |
重置视图(zoomable 时恢复 100% 并居中) |
addNode(parentId, side, nodeData) |
命令式新增子节点,组件内部合并到当前树 |
centerNodeById(nodeId, duration?) |
将指定节点居中到视口 |
<node-tree ref="tree" :data="treeData" />
this.$refs.tree.zoomIn()
this.$refs.tree.addNode('root-id', 'right', {
id: 'new-1',
title: '新节点'
})
Events
| 事件 |
参数 |
说明 |
node-click |
(data, layoutNode) |
点击节点 |
node-added |
(nodeData, parentId, side) |
通过 addNode 成功添加节点 |
add-node-request |
(parentData, side) |
点击添加按钮且未提供 createChildNode 时触发 |
update:scale |
(scale) |
缩放变化 |
update:collapsedIds |
(ids) |
收起状态变化 |
toggle |
(data, layoutNode, collapsed) |
展开/收起 |
load-start / load-success / load-error |
— |
异步加载生命周期 |
Slots
node(scoped slot)
自定义节点 DOM:
<node-tree :data="treeData">
<template #node="{ data, node, toggle, loading, loadChildren, isVisible }">
<div class="my-card">{{ data.title }}</div>
</template>
</node-tree>
Core API
若只需布局算法:
import { layoutForest, insertTreeNode } from '@1samare/node-tree/core'
const layout = layoutForest(treeData, {
layoutDirection: 'horizontal',
nodeWidth: 320,
verticalGap: 24
})
const nextTree = insertTreeNode(treeData, 'parent-id', 'right', {
id: 'child-id',
title: 'Child'
})
本地开发
npm install
npm run dev # 启动 playground
npm run test # 运行测试
npm run build # 构建 dist
License
MIT