@bdsoft/tree
v1.1.8
Published
内部分类树组件,支持折叠、排序、搜索
Readme
@bdsoft/tree 树组件
BdTree 是基于 Element Plus ElTree 的内部分类树组件,支持静态数据、URL 数据、搜索、右键菜单、拖拽排序、自定义渲染,以及可选的 Ctrl/Cmd 多选、Shift 同级连选、右键剪切/粘贴和局部编辑删除。
组件外围容器必须设置高度。
安装依赖
如果主项目已经安装 @bdsoft/element,通常无需额外配置。旧项目如需全局挂载 Vue 与 Element Plus,可按原方式处理:
import * as Vue from 'vue'
window.Vue = Vue
import * as ElementPlus from 'element-plus'
window.ElementPlus = ElementPlus基础用法
<template>
<div style="height: 360px">
<BdTree
ref="treeRef"
isTreeData
:treeDatas="treeData"
:defaultProps="defaultProps"
:isUrlLoad="false"
:draggable="false"
@treeNodeClick="handleNodeClick"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { BdTree } from '@bdsoft/tree'
const treeRef = ref()
const defaultProps = {
children: 'items',
label: 'title',
id: 'id',
pid: 'parentid',
sequence: 'sequence',
isLeaf: 'isLeaf'
}
const treeData = ref([
{
id: '0',
title: '数据目录',
isroot: true,
items: [
{ id: '1', parentid: '0', title: '分类一', items: [] }
]
}
])
const handleNodeClick = (data, node) => {
console.log(data, node)
}
</script>未显式传入 isExpandALl、expandKeys、expandId 时,组件会默认展开根节点和一级有子节点目录。需要完全自定义展开状态时,请传入 expandKeys 或 expandId。
多选、剪切与粘贴
<BdTree
ref="treeRef"
isTreeData
isContextmenu
enableMultiSelect
enableCutPaste
:treeDatas="treeData"
:defaultProps="defaultProps"
:isUrlLoad="false"
:menuData="menuData"
@selectedChange="handleSelectedChange"
@cutTreeNodes="handleCut"
@pasteTreeNodes="handlePaste"
@updateTree="handleUpdateTree"
/>交互规则:
- 普通点击:单选节点,并保持原有
treeNodeClick/treeNodeDbClick行为。 - Ctrl/Cmd 点击:切换当前节点选中状态,只触发
selectedChange。 - Shift 点击:仅在同一父节点的兄弟节点范围内连选;跨父级时退化为单选当前节点。
- 右键未选中节点:先选中当前节点;右键已选中节点:保留当前多选集合。
- 右键“剪切”:记录当前选中节点。若同时选中父子节点,只保留最外层父节点。
- 右键“粘贴”:默认把剪切节点作为目标节点子节点插入,并更新
pid、sequence。 - 禁止剪切根节点,禁止粘贴到自身或自身后代中。
局部编辑与删除
业务保存成功后,可以直接调用组件暴露的方法局部更新树,不需要 reloadCategoryTree 刷新整棵树。
// 编辑节点标题
treeRef.value?.updateNodeByKey('node-1', {
title: '新的节点名称'
})
// 也可以使用 updater
treeRef.value?.updateNodeByKey('node-1', (node) => ({
title: `${node.title}(已编辑)`
}))
// 删除一个或多个节点
treeRef.value?.removeNodeByKey('node-1')
treeRef.value?.removeNodeByKey(['node-1', 'node-2'])updateNodeByKey 和 removeNodeByKey 都会触发 updateTree(flatData, null, null, meta),其中 meta.action 分别为 edit 和 delete。
右键菜单
右键菜单仍兼容原有 menuData + emitter 模式:
import { emitter } from '@bdsoft/utils'
const menuData = [
{ value: 'addcategory', label: '添加', icon: 'add' },
{ value: 'editcategory', label: '编辑', icon: 'edit' },
{ value: 'delcategory', label: '删除', icon: 'del' }
]
onMounted(() => {
emitter.on('editcategory', (node) => {
treeRef.value?.updateNodeByKey(node.id, { title: `${node.title}(已编辑)` })
})
emitter.on('delcategory', (node) => {
treeRef.value?.removeNodeByKey(node.id)
})
})开启 enableCutPaste 后,组件会在业务菜单后追加内置“剪切”“粘贴”菜单项;业务菜单事件仍按 value 通过 emitter 触发。
Props
| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| treeDatas | Array | - | 静态树数据。 |
| rootData | Array | [{ title: '数据目录', id: '0', ... }] | 根节点数据。 |
| isTreeData | Boolean | false | 是否直接使用 treeDatas 作为完整树。 |
| isUrlLoad | Boolean | true | 是否通过 URL 加载数据。 |
| treeUrl | String | - | URL 数据加载地址。 |
| treeParms | Object | - | URL 加载附加参数。 |
| bdsdk / sdkparms | Object | - | URL 加载使用的 SDK。 |
| defaultProps | Object | { children, label, isLeaf, id, pid, sequence } | 字段映射。 |
| menuData | Array | [] | 右键菜单配置。 |
| isContextmenu | Boolean | false | 是否启用右键菜单。 |
| isReadonly | Boolean | false | 只读模式,禁用拖拽和右键菜单。 |
| showSearcher | Boolean | true | 是否显示搜索框。 |
| showSearcherPos | String | bottom | 搜索框位置:top / bottom。 |
| filterName | String | title | 搜索匹配字段。 |
| showExpandMenu | Boolean | true | 是否显示展开/折叠按钮。 |
| isExpandALl | Boolean | false | 是否默认展开所有节点。 |
| expandKeys | Array | [] | 默认展开的节点 key。 |
| expandId | String \| Array | '' | 需要展开或折叠保护的节点 key。 |
| draggable | Boolean | true | 是否允许拖拽。 |
| treeAllowDrag | Function | 禁止根节点拖拽 | 拖拽允许判断。 |
| treeAllowDrop | Function | 限制根节点放置规则 | 放置允许判断。 |
| isAccordion | Boolean | false | 是否开启手风琴模式。 |
| expandClickNode | Boolean | false | 点击节点时是否展开/收缩。 |
| enableMultiSelect | Boolean | false | 开启 Ctrl/Cmd 多选和 Shift 同级连选。 |
| enableCutPaste | Boolean | false | 开启右键剪切/粘贴。 |
| cutPastePlacement | String | inner | 粘贴位置:inner / before / after。 |
Events
| 事件 | 参数 | 说明 |
| --- | --- | --- |
| treeNodeClick | (data, node) | 普通单击节点。 |
| treeNodeDbClick | (data, node) | 双击节点。 |
| handleCheckChange | (nodes) | 勾选节点变化。 |
| selectedChange | (selectedNodes, selectedKeys) | 多选集合变化。 |
| cutTreeNodes | (payload) | 执行剪切后触发。 |
| pasteTreeNodes | (payload) | 执行粘贴后触发。 |
| updateTree | (flatData, draggingNode, dropNode, meta) | 拖拽、粘贴、局部编辑、局部删除后触发。 |
pasteTreeNodes 的 payload:
{
nodes: [], // 被移动节点快照
keys: [], // 被移动节点 key
target: {}, // 粘贴目标节点快照
targetKey: '', // 粘贴目标 key
placement: 'inner',
flatData: [] // 更新后的扁平树数据
}Expose 方法
| 方法 | 说明 |
| --- | --- |
| setCheckedKeys(keys, leafOnly) | 设置勾选节点。 |
| getCheckedKeys() | 获取勾选节点 key。 |
| getNode(id) | 获取 Element Plus Tree 节点实例。 |
| setCurrentKey(id) | 设置当前高亮节点。 |
| getCurrentNode() | 获取当前高亮节点数据。 |
| getChildren() | 获取当前树数据。 |
| setFilterText(val) | 设置搜索过滤词。 |
| getExpandKeys() | 获取当前展开节点 key。 |
| showLoading(isloading) | 控制骨架屏加载态。 |
| append(data, refNode) | 在节点内追加。 |
| insertBefore(data, refNode) | 在节点前插入。 |
| remove(refNode) | 调用 Element Plus Tree 删除节点。 |
| getSelectedNodes() | 获取多选节点数据。 |
| getSelectedKeys() | 获取多选节点 key。 |
| clearSelectedNodes() | 清空多选状态。 |
| updateNodeByKey(key, patchOrUpdater) | 局部更新节点。 |
| removeNodeByKey(keyOrKeys) | 局部删除节点。 |
| cutSelectedNodes() | 剪切当前多选节点。 |
| pasteCutNodes(targetData, placement) | 粘贴已剪切节点。 |
Demo
packages/bd-tree/demos/ 下包含以下示例:
default-expand.vue:默认展开根节点和一级目录。multi-select-cut-paste.vue:Ctrl/Cmd 多选、Shift 同级连选、右键剪切粘贴。local-edit-delete.vue:局部编辑和删除,不刷新整棵树。right-menu-composed.vue:业务右键菜单与内置剪切粘贴组合使用。
DragTree 仍用于多树拖拽场景,本次新增的多选剪切粘贴能力只加在 BdTree 主组件上。
