@1samare/node-tree
v0.6.1
Published
A high-performance bidirectional tree layout component with Vue 2 adapter.
Maintainers
Readme
@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 # 构建 distLicense
MIT
