目录
1.简介
2.安装及使用
下载包
main.js全局引用
页面使用
数据要求
配合使用
3.基础使用
4.较深入使用
5.修改后的代码如下
一个不算太简易的简易版组织架构图,组件依赖于vue-org-tree, 在此基础上将部分源代码进行优化修改。增加鼠标拖拽和鼠标滚轮缩放,并支持节点拖拽,以及节点编辑等功能。
优势:
1.支持整体拖拽、自定义展开组织树展开层级;
2.可进行节点搜索,显示搜索节点相关的组织树;
3.支持自定义节点样式,自定义新增、编辑、删除、节点是否拖拽、拖拽节点副本/节点;
做demo进行测试时发现一个缺点:当数据从1800条左右开始时,拖拽合并速度太快且频繁拖拽合并时,会报错数据找不到(感觉是上一轮拖拽数据还没有处理完,下一轮数据处理不了了,希望有大佬能解惑,能有好的解决办法)。
vue2的版本:zm-tree-org (gitee.io)
vue3的版本:Home | vue3-tree-org (sangtian152.github.io)
git源码:GitHub - sangtian152/zm-tree-org: 一个简易版组织架构图,组件依赖于vue-org-tree, 在此基础上将部分源代码进行优化修改。支持鼠标拖动,鼠标滚轮缩放,节点拖拽。
以vue2的版本示例。
npm i zm-tree-org -S
import Vue from 'vue'; import ZmTreeOrg from 'zm-tree-org'; import "zm-tree-org/lib/zm-tree-org.css"; Vue.use(ZmTreeOrg);
//使用示例:修改背景色/文字颜色
最外层(公司级)是Object,其子级及以下为Array。
orgData:{ id: 1, //组织id,必须 label: "xxx科技有限公司", //组织名称,必须 disabled: true, //是否可编辑 children: [ //子级 { id: 2, //子级组织id,必须 pid: 1, //父级组织id,必须 label: "产品研发部", //组织名称,必须 expand: false, //当前节点下的节点是否默认展开 noDragging: true, //当前节点是够允许拖拽 children: [] } }
页面部分功能需结合elementUI使用。
下载
npm i element-ui -S
main.js全局引用
import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
(1)树形结构横向/纵向展开;
(2)树形结构展开/收起;
(3)组织树默认展开层级 or 单一某节点的子节点树展开/收起;
单一某节点的详细说明:
需对数据做处理,单一节点的子节点树不填写默认跟随:default-expand-level。
示例:{id: 6,pid: 2,label: "展开当前节点的组织树",expand: true}。
如组件绑定 :default-expand-level="num"
且 num+1 < 当前设置的层级 上述设置不生效;
num+1 >= 当前设置的层级 上述设置生效。
num+1举例:expand:false,即使 num+1 >= 当前设置的层级,当前节点的子节点树也会收起。
文中最开始的示例图全部展开后共为 2级子节点(num) + 1 级根节点(所以num需要加1)。:default-expand-level="1"时,代表展开到第一级子节点,即“产品研发部”及它的同层级。
(4)组织树 可编辑/不可编辑 or 单一某节点 可编辑/不可编辑;
单一某节点的详细说明:
需对数据做处理,子节点不填写默认为false(可编辑)。
子节点示例:{id: 6,pid: 2,label: "禁止编辑节点",disabled: true}。
如组件绑定 :disabled="true" 上述设置被覆盖;:disabled="false",上述设置生效。
(5)节点树整体 可拖拽/不可拖拽 or 单一某节点 可拖拽/不可拖拽
单一某节点的详细说明:
需对数据做处理,子组件不填写默认为false(可拖拽)。
示例:{id: 6,pid: 2,label: "禁止拖拽节点",noDragging: true}。
如组件绑定 :node-draggable="true" 上述设置也生效; :node-draggable="false",上述设置被覆盖。
(6)拖拽节点副本、当前位置保留节点本身 / 拖拽节点本身;
(7)仅拖动当前节点、子节点添加到当前节点 / 当前节点及子节点一起拖动;
(8)在线调整组织结构任意背景色;
(9)在线调整文字任意颜色;
//color为string类型 :label-
(10)搜索组织,同时显示当前组织的上级所有组织;
filter(){ this.$refs.tree.filter(this.keyword) }
(1)自定义节点右键点击事件修改;
如仅修改name,则仅修改显示的文字,插件自带的【编辑】样式依然显示;
如修改command值,则绑定右键菜单弹出和【复制】【新增】【编辑】【删除】4个可自定义的绑定事件失效,需重写写入事件。
例如:仅将command:'edit'修改为command:'edit1',如果某子节点为不可编辑状态,点击右键,依然会显示菜单【复制】【编辑】,但点击【编辑】事件无反应。如果不想【编辑】功能显示,可以绑定vue的@contextmenu.prevent,对menus进行动态赋值。
// data值 menus: [{ name: '复制文本', command: 'copy' }, { name: '新增节点', command: 'add' }, { name: '编辑节点', command: 'edit1' }, { name: '删除节点', command: 'delete' }], disaled: false, //自定义节点绑定方法 //动态赋值 terFun(node) { console.log(node) if (node.disabled || this.disaled) { this.menus = [{ name: '复制文本', command: 'copy' }] } else { this.menus = [ { name: '复制文本', command: 'copy' }, { name: '新增节点', command: 'add' }, { name: '编辑节点', command: 'edit1' }, { name: '删除节点', command: 'delete' } ] } },
(2)自定义节点及自定义编辑节点。
在4-(1)的基础上去做,需要修改自定义点击右键事件的edit值,否则插件自带的【编辑节点】样式依然会闪烁显示。
———————— Html说明 ————————
// 插件的自定义节点插槽 // 此处可修改组织树的节点样式,当前为默认 {{ node.label }} // 组织名称 // 此处的class为late的 div为自定义的【编辑节点】card确定
———————— data说明 除node.disabled外,可自定义————————
treeScope: false, //是否显示【自定义编辑】card node.disabled: 查找当前节点可编辑/不可编辑的属性 cardOne: {}, //【自定义编辑】card组件信息 node.open: //自定义的节点【编辑属性值】
———————— function说明 ————————
@on-contextmenu="onMenus" //右键菜单点击事件 如修改【4、自定义节点右键点击菜单修改的command:'edit'值,则插件自带编辑事件失效,需自定义,自定义如下】 onMenus({ node, command }) { // 自定义编辑 if (command === 'edit1' && !node.disabled) { //显示【自定义编辑】card,将node赋值给cardOne //自定义编辑--card } },
组件自带的默认编辑节点样式:
修改后的实现效果:
弹窗自定义编辑节点
标签自定义编辑节点
{{ horizontal? "横向": "纵向" }} {{ collapsable? "可收起": "仅展开" }} {{ disaled? "禁止编辑": "可编辑" }} {{ onlyOneNode? "仅拖动当前节点": "拖动当前节点树" }} {{ cloneNodeDrag? "拖动节点副本": "拖动节点本身" }} {{ pop? "弹窗修改节点": "标签修改节点" }} 背景色: 文字颜色: 搜索: {{ node.label }} 确定 {{ node.children.length }}
.json数据
{ "orgAll":{ "id": 1, "label": "xxx科技有限公司", "disabled": true, "children": [ { "id": 2, "pid": 1, "label": "产品研发部", "expand": false, "children": [ { "id": 6, "pid": 2, "label": "禁止编辑节点", "disabled": true }, { "id": 8, "pid": 2, "label": "禁止拖拽节点", "noDragging": true }, { "id": 7, "pid": 2, "label": "研发-后端", "children": [ { "id": 14, "pid": 7, "label": "后端1组" }, { "id": 15, "pid": 7, "label": "后端2组" } ] }, { "id": 13, "pid": 2, "label": "研发-前端" }, { "id": 9, "pid": 2, "label": "产品经理" }, { "id": 10, "pid": 2, "label": "测试" } ] }, { "id": 3, "pid": 1, "label": "客服部", "children": [ { "id": 11, "pid": 3, "label": "客服一部" }, { "id": 12, "pid": 3, "label": "客服二部" } ] }, { "id": 4, "pid": 1, "label": "业务部" }, { "id": 5, "pid": 1, "label": "人力资源中心" } ] } }