关于组织架构图,效果图如下:
之前我是用jq
写过一个组织架构图,文章链接如下:当时是用的jOrgChart
jq版本的组织架构图:http://t.csdn.cn/7gkCm
当时对jOrgChart
不是很熟,因此在写的时候遇到了很多问题,虽然最终实现了功能,但并不完美。
今天在看不同的后台管理系统框架,看到了iview-vue
,在这个框架中看到了组织架构图,进而知道了vue-org-tree
这个插件,可以实现vue
版本的组织架构图。
简易版效果图如下:
我从网上找到一个大神关于vue-org-tree
这个插件的详细使用步骤,大神写的非常的详细,我基本上都是参照大神完成的。
大神关于vue-org-tree
插件的具体使用步骤:https://www.cnblogs.com/10ve/p/12573772.html
附上vue-org-tree
的github
链接:
vue-org-tree
插件的github
链接:https://github.com/hukaibaihu/vue-org-tree#readme
下面将我的步骤记录如下:
1.vue
插件下载,也可以直接cdn
引入
我刚开始是按照github
上的安装的,后来发现安装之后有问题,因此我直接按照大神提供的思路进行安装了。
npm install vue-tree-color
——安装vue-tree-color
,注意不是vue-org-tree
2.安装less
和less-loader
安装less
和less-loader
之前,确定当前系统中是否已经安装过了less
lessloaer
,可以找到package.json
文件,在此文件中检索less
和less-loader
。
npm install --save-dev less less-loader
3.在main.js
中引入vue-org-tree
插件
import Vue from 'vue'
import Vue2OrgTree from 'vue-tree-color'
Vue.use(Vue2OrgTree)
4.运行项目,此时报错了
报错信息:Syntax Error: TypeError: this.getOptions is not a function
于是,百度:
大神解决vue
安装less lessloader
插件报错问题:https://blog.csdn.net/zhangyuying_777/article/details/115114147
报错原因及解决办法:
需要在安装less
和lessloader
时,指定版本号,否则就会导致兼容问题。
npm i less@3.9.0 less-loader@4.1.0 -D
安装完成后,再次运行,成功。
5.使用vue-org-tree
插件
由于之前在main.js
中已经引入插件到全局了,则此时可以直接在页面中使用
template
中的写法
我下了横向和纵向两种,
- data:就是数据格式,时一个对象,具体格式下面有示例
- horizontal:默认是false,即纵向展示
- label-class-name:可以给节点添加的类名,不过我这边使用了没有效果,下面有其他方法来处理节点样式,评论区有小伙伴改成函数的写法,生效了,大家可以尝试一下
- collapsable:是否折叠,有这个属性,则表示默认折叠,有其他方法可以在存在此属性时,也保证是展开状态
- on-expand:点击折叠点,点击可以展开,再次点击可以折叠,是个方法
- on-node-click:顾名思义,就是点击节点,触发的事件
- on-node-mouseover:鼠标移入节点触发的事件,可以触发一个弹层用于展示详情
- on-node-mouseout:鼠标移出节点触发的事件,可以控制详情弹层的隐藏
<vue2-org-tree
:data="data"
:horizontal="true"
:label-class-name="labelClassName"
collapsable
@on-expand="onExpand"
@on-node-click="NodeClick"
@on-node-mouseover="onMouseover"
@on-node-mouseout="onMouseout"
:renderContent="renderContent"
/>
<vue2-org-tree
:data="data"
:label-class-name="labelClassName"
collapsable
@on-expand="onExpand"
@on-node-click="NodeClick"
@on-node-mouseover="onMouseover"
@on-node-mouseout="onMouseout"
:renderContent="renderContent"
/>
<!-- 创建浮窗盒子 -->
<div v-show="basicSwitch" class="floating">
<p>ID:{{BasicInfo.id}}</p>
<p>Name:{{BasicInfo.label}}</p>
</div>
js
中的写法
data
的数据结构
data(){
return{
labelClassName: "bg-color-orange",
basicInfo: { id: null, label: null },
basicSwitch: false,
data: {
id: 0,
label: "XXX科技有限公司",
children: [
{
id: 2,
label: "产品研发部",
children: [
{
id: 5,
label: "研发-前端",
children: [
{
id: 55,
label: "前端1"
},
{
id: 56,
label: "前端2"
},
{
id: 57,
label: "前端3"
},
{
id: 58,
label: "前端4"
}
]
},
{
id: 6,
label: "研发-后端"
},
{
id: 9,
label: "UI设计"
},
{
id: 10,
label: "产品经理"
}
]
},
{
id: 3,
label: "销售部",
children: [
{
id: 7,
label: "销售一部"
},
{
id: 8,
label: "销售二部"
}
]
},
{
id: 4,
label: "财务部"
},
{
id: 9,
label: "HR人事"
}
]
},
}
},
methods:{
//渲染节点
renderContent(h, data) {
return (
<div>
<div>
<i class="el-icon-user-solid"></i>
<span>{data.label}</span>
<span>男</span>
</div>
<div style="font-size:12px;line-height:20px;">测试人员</div>
</div>
);
},
//鼠标移出
onMouseout(e, data) {
this.basicSwitch = false;
},
//鼠标移入
onMouseover(e, data) {
this.basicInfo = data;
this.basicSwitch = true;
var floating = document.getElementsByClassName("floating")[0];
floating.style.left = e.clientX + "px";
floating.style.top = e.clientY + "px";
},
//点击节点
NodeClick(e, data) {
console.log(e, data);
},
//默认展开
toggleExpand(data, val) {
if (Array.isArray(data)) {
data.forEach(item => {
this.$set(item, "expand", val);
if (item.children) {
this.toggleExpand(item.children, val);
}
});
} else {
this.$set(data, "expand", val);
if (data.children) {
this.toggleExpand(data.children, val);
}
}
},
collapse(list) {
list.forEach(child => {
if (child.expand) {
child.expand = false;
}
child.children && this.collapse(child.children);
});
},
//展开
onExpand(e, data) {
if ("expand" in data) {
data.expand = !data.expand;
if (!data.expand && data.children) {
this.collapse(data.children);
}
} else {
this.$set(data, "expand", true);
}
},
}
上面代码中,有个渲染节点的函数,因为默认的样式是只展示标签中的label
字段,但是实际应用场景中,经常需要展示其他的字段,则此时可以通过渲染节点的函数,对节点进行重新编写及样式调整。
就是下面的函数:
renderContent(h, data) {
return (
<div>
<div>
<i class="el-icon-user-solid"></i>
<span>{data.label}</span>
<span>男</span>
</div>
<div style="font-size:12px;line-height:20px;">测试人员</div>
</div>
);
},
注意:在渲染函数中,变量可以直接通过{}单大括号来进行展示,而不是template中的双大括号的展示形式
通过上面的代码,就可以实现下面的效果了:
此处的渲染节点的函数写法,在插件文档上其实是没有详细描述的,我是百度查找到的答案。
vue中使用tree自定义节点时的render-content的链接:https://blog.csdn.net/weixin_42329676/article/details/89713008
虽然不是同一个组件,但是写法是可以借鉴的:
我在上面提供的渲染方法的基础上,修改后同样实现了渲染组织架构图节点的效果。
上面还提到了,节点样式处理,当无法通过label-class-name
来进行调整样式时,可以通过下面的方式来处理:
.org-tree-node-label-inner {
color: #fff;
background-color: orange;
}
label-class-name
:可以给节点添加的类名,不过我这边使用了没有效果,下面有其他方法来处理节点样式,评论区有小伙伴改成函数的写法,生效了,大家可以尝试一下。
完成!!!