A virtual tree component for Vue.js
bash
npm install virtual-tree-component --save
`
$3
`bash
yarn add virtual-tree-component
`
依赖
- Vue.js:^2.6.14
- vue-virtual-scroller:^1.1.2
- Element UI:可选,组件样式基于 Element UI Tree
快速开始
$3
`javascript
import Vue from 'vue'
import VirtualTree from 'virtual-tree-component'
import 'virtual-tree-component/assets/index.scss'
Vue.component('virtual-tree', VirtualTree)
`
$3
`vue
:data="treeData"
:height="400"
:item-size="26"
@node-click="handleNodeClick"
/>
`
API
$3
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| 基础配置 | | | |
| data | Array | [] | 树的数据源 |
| height | [String, Number] | 0 | 树的高度,设置后启用虚拟滚动 |
| item-size | Number | 26 | 每个节点的高度(单位:px) |
| props | Object | { children: 'children', label: 'label', disabled: 'disabled' } | 配置树节点的属性 |
| node-key | String | - | 每个树节点用来作为唯一标识的属性 |
| 显示配置 | | | |
| show-checkbox | Boolean | false | 是否显示复选框 |
| highlight-current | Boolean | false | 是否高亮当前选中节点 |
| indent | Number | 18 | 相邻级节点间的水平缩进,单位为像素 |
| icon-class | String | - | 自定义树节点的图标 |
| render-content | Function | - | 自定义节点内容 |
| 交互配置 | | | |
| expand-on-click-node | Boolean | true | 是否在点击节点的时候展开或者收缩节点 |
| check-on-click-node | Boolean | false | 是否在点击节点的时候选中节点 |
| auto-expand-parent | Boolean | true | 是否自动展开父节点 |
| default-expand-all | Boolean | false | 是否默认展开所有节点 |
| default-expanded-keys | Array | [] | 默认展开的节点的 key 的数组 |
| default-checked-keys | Array | [] | 默认选中的节点的 key 的数组 |
| current-node-key | [String, Number] | - | 当前选中的节点 |
| check-strictly | Boolean | false | 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法 |
| check-descendants | Boolean | false | 当 check-strictly 为 false 时,是否自动检查子节点 |
| draggable | Boolean | false | 是否开启拖拽功能 |
| allow-drag | Function | - | 拖拽时判定节点是否可拖拽的函数 |
| allow-drop | Function | - | 拖拽时判定目标节点能否被放置的函数 |
| 性能配置 | | | |
| render-after-expand | Boolean | true | 是否在第一次展开某个树节点后才渲染其子节点 |
| lazy | Boolean | false | 是否懒加载子节点,需与 load 方法结合使用 |
| load | Function | - | 加载子树数据的方法,仅当 lazy 属性为 true 时生效 |
| keeps | Number | 40 | 虚拟滚动中保持的节点数量 |
| extra-line | Number | 8 | 虚拟滚动中额外渲染的行数 |
| 其他配置 | | | |
| accordion | Boolean | false | 是否每次只打开一个同级树节点 |
| filter-node-method | Function | - | 对树节点进行筛选时执行的方法 |
| empty-text | String | '暂无数据' | 内容为空时的提示文本 |
$3
| 事件名称 | 回调参数 | 说明 |
|----------|----------|------|
| node-click | data, node, component | 节点被点击时触发 |
| node-contextmenu | event, data, node, component | 节点被鼠标右键点击时触发 |
| node-dblclick | data, node, component | 节点被双击时触发 |
| node-expand | data, node, component | 节点被展开时触发 |
| node-collapse | data, node, component | 节点被折叠时触发 |
| node-check | data, checked, node | 节点复选框被点击时触发 |
| check-change | data, checked, indeterminate | 节点选中状态发生变化时触发 |
| current-change | data, node | 当前选中节点变化时触发 |
| node-drag-start | node, event | 节点开始拖拽时触发 |
| node-drag-enter | draggingNode, dropNode, dropType | 拖拽进入其他节点时触发 |
| node-drag-leave | draggingNode, dropNode | 拖拽离开节点时触发 |
| node-drag-over | draggingNode, dropNode, event | 拖拽经过节点时触发 |
| node-drag-end | draggingNode, dropNode, dropType, event | 拖拽结束时触发 |
| node-drop | draggingNode, dropNode, dropType, event | 拖拽成功完成时触发 |
$3
| 方法名 | 参数 | 说明 |
|--------|------|------|
| filter | value | 对树节点进行筛选操作 |
| updateKeyChildren | key, data | 通过 key 更新节点的子节点 |
| append | data, parentNode | 为某个节点追加子节点 |
| remove | data | 删除某个节点 |
| insertBefore | data, refNode | 在参考节点前插入节点 |
| insertAfter | data, refNode | 在参考节点后插入节点 |
| getCheckedNodes | leafOnly, includeHalfChecked | 如果节点可被选择(show-checkbox 为 true),则返回当前选中的节点 |
| getCheckedKeys | leafOnly | 如果节点可被选择(show-checkbox 为 true),则返回当前选中节点的 key 组成的数组 |
| setCheckedNodes | nodes | 设置目前勾选的节点,使用此方法必须设置 node-key 属性 |
| setCheckedKeys | keys, leafOnly | 通过 keys 设置目前勾选的节点,使用此方法必须设置 node-key 属性 |
| setChecked | data, checked, deep | 设置节点是否选中,使用此方法必须设置 node-key 属性 |
| getCurrentNode | - | 获取当前被选中的节点 |
| setCurrentNode | node | 设置当前选中的节点,使用此方法必须设置 node-key 属性 |
| getNode | data | 根据 data 或者 key 拿到对应的 node |
高级用法
$3
通过设置 height 属性启用虚拟滚动:
`vue
:data="treeData"
:height="400px"
:item-size="26"
:default-expand-all="true"
/>
`
$3
使用 render-content 属性自定义节点内容:
`vue
:data="treeData"
:height="400"
:render-content="renderContent"
/>
`
$3
启用拖拽功能:
`vue
:data="treeData"
:height="400"
:draggable="true"
@node-drop="handleNodeDrop"
/>
`
$3
启用懒加载功能:
`vue
:data="treeData"
:height="400"
:lazy="true"
:load="loadNode"
node-key="id"
/>
`
版本依赖要求
| Vue Version | Virtual Tree Version | vue-virtual-scroller Version |
|-------------|----------------------|-------------------------------|
| Vue 2.6.x | ^1.0.0 | ^1.1.2 |
| Vue 2.7.x | ^1.0.0 | ^1.1.2 |
注意事项
1. 虚拟滚动模式下:
- 必须设置 height 属性才能启用虚拟滚动
- 建议设置固定的 item-size,确保滚动位置准确
- 节点内容应保持固定高度,避免高度变化影响滚动
2. 性能优化:
- 对于大数据量,建议使用 node-key 属性提高节点查找效率
- 复杂节点内容建议使用 render-content 而非插槽
- 启用 render-after-expand 可以减少初始渲染时间
3. 兼容性:
- 兼容 Element UI Tree 的大部分 API,但某些高级功能可能有所不同
- 支持现代浏览器,IE11 可能需要额外的 polyfill
4. 样式问题:
- 组件样式基于 Element UI Tree,建议引入 Element UI 样式
- 或根据需要自定义样式
许可证
MIT
贡献
欢迎提交 Issue 和 Pull Request!
更新日志
$3
- 初始版本发布
- 支持虚拟滚动
- 兼容 Element UI Tree API
- 支持拖拽、多选、懒加载等功能
常见问题
$3
A: 请检查以下几点:
- 确保 height 属性值大于 0
- 确保数据已正确加载
- 检查是否有样式冲突导致高度计算错误
$3
A: 请检查:
- 是否已设置 draggable 为 true
- 确保已设置 node-key 属性
- 检查 allow-drag 和 allow-drop 函数是否返回正确值
$3
A: 请检查:
- render-content 函数是否正确返回 VNode
- 节点数据的 label` 属性是否存在