vue组织结构插件vue2-org-tree 功能交互
先上效果 可以切换节点颜色,展开与否,坚排或者横排都可以配置。
安装
安装vue2-org-tree, 然后再安装样式 less-loade
cnpm install --save-dev less less-loader
cnpm install --save-dev vue2-org-tree
或者:
npm i vue2-org-tree -S
npm install --save-dev less less-loader –S
安装完成后,vue2项目根目录下package.json自动更新以上 2个包信息
"dependencies": {
"core-js": "^3.8.3",
"echarts": "^5.4.0",
"element": "^0.1.4",
"element-ui": "^2.15.10",
"install": "^0.13.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"moment": "^2.29.4",
"vue": "^2.6.14",
"vue-router": "^3.5.2",
"vue2-org-tree": "^1.3.6"
},
项目源码:
main.js
TreeTest.vue
<template>
<div ref="appContainer" class="app-container">
<div style="margin-left:30px;">
<el-row :gutter="20">
<el-col :span="5">
<el-switch v-model="horizontal" :width="50" active-text="横排" inactive-text="竖排" style="margin-top:8px;"/>
</el-col>
<el-col :span="5">
<el-switch v-model="expandAll" :width="50" active-text="全部展开"
inactive-text="全部折叠" style="margin:8px;" @change="expandChange"/>
</el-col>
<el-col :span="14">
<span style="font-size:14px;font-weight:500;">选择背景色:</span>
<el-select v-model="labelClassName" @change="selectChange">
<el-option value="bg-white" label="白色">白色</el-option>
<el-option value="bg-orange" label="橘黄色">橘黄色</el-option>
<el-option value="bg-gold" label="金色">金色</el-option>
<el-option value="bg-gray" label="灰色">灰色</el-option>
<el-option value="bg-lightpink" label="浅粉色">浅粉色</el-option>
<el-option value="bg-chocolate" label="巧克力色">巧克力色</el-option>
<el-option value="bg-tomato" label="番茄色">番茄色</el-option>
</el-select>
</el-col>
</el-row>
</div>
<div style="font-size:12px;margin-top:30px;">
<el-scrollbar :style="scrollTreeStyle" class="el-org-tree">
<vue2-org-tree
:data="treeData.data"
:horizontal="!horizontal"
:collapsable="collapsable"
:label-class-name="labelClassName"
:render-content="renderContent"
name="organ"
@on-expand="onExpand"
@on-node-click="onNodeClick"/>
</el-scrollbar>
</div>
<br/><br/>
</div>
</template>
<script>
export default {
name: "TreeTest",
data() {
return {
"treeData": {
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人事"
}
]
},
}
,
horizontal: true, //横版 竖版
collapsable: false,
expandAll: true, //是否全部展开
labelClassName: '白色', // 默认颜色
scrollTreeStyle: 'width:100%;',
}
},
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.treeData.basicSwitch = false;
},
//鼠标移入
onMouseover(e, data) {
this.treeData.basicInfo = data;
this.treeData.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);
}
},
getList() {
// 后台回去的数据 赋值给data即可
},
// 自定义您的点击事件
onNodeClick(e, data) {
alert("点击")
},
expandChange() {
this.collapsable = true
this.toggleExpand(this.treeData.data, this.expandAll)
},
selectChange(){
}
}
}
</script>
<!--<style scoped>-->
<!--</style>-->
<style lang="less">
.bg-white {
background-color: white;
}
.bg-orange {
background-color: orange;
}
.bg-gold {
background-color: gold;
}
.bg-gray {
background-color: gray;
}
.bg-lightpink {
background-color: lightpink;
}
.bg-chocolate {
background-color: chocolate;
}
.bg-tomato {
background-color: tomato;
}
//.org-tree-node-label-inner {
// color: #fff;
// background-color: orange;
//}
.el-org-tree {
.el-scrollbar__wrap {
overflow-x: hidden;
}
.org-tree-node-label {
white-space: nowrap;
}
.el-tree-node__content{
background: white;
}
.org-tree-node-label .org-tree-node-label-inner {
padding-top: 8px;
padding-right: 10px;
padding-bottom: 5px;
padding-left: 10px;
cursor: pointer;
}
.horizontal .org-tree-node.is-leaf {
padding-top: 5px;
padding-bottom: 5px;
}
}
</style>
App.vue
<template>
<div ref="appContainer" class="app-container">
<div style="margin-left:30px;">
<el-row :gutter="20">
<el-col :span="5">
<el-switch v-model="horizontal" :width="50" active-text="横排" inactive-text="竖排" style="margin-top:8px;"/>
</el-col>
<el-col :span="5">
<el-switch v-model="expandAll" :width="50" active-text="全部展开" inactive-text="全部折叠" style="margin-top:8px;" @change="expandChange"/>
</el-col>
<el-col :span="14">
<span style="font-size:14px;font-weight:500;">选择背景色:</span>
<el-select v-model="labelClassName" @change="selectChange">
<el-option value="bg-white" label="白色">白色</el-option>
<el-option value="bg-orange" label="橘黄色">橘黄色</el-option>
<el-option value="bg-gold" label="金色">金色</el-option>
<el-option value="bg-gray" label="灰色">灰色</el-option>
<el-option value="bg-lightpink" label="浅粉色">浅粉色</el-option>
<el-option value="bg-chocolate" label="巧克力色">巧克力色</el-option>
<el-option value="bg-tomato" label="番茄色">番茄色</el-option>
</el-select>
</el-col>
</el-row>
</div>
<div style="font-size:12px;margin-top:30px;">
<el-scrollbar :style="scrollTreeStyle" class="el-org-tree">
<vue2-org-tree
:data="treeData"
:horizontal="!horizontal"
:collapsable="collapsable"
:label-class-name="labelClassName"
:render-content="renderContent"
name="organ"
@on-expand="onExpand"
@on-node-click="onNodeClick"/>
</el-scrollbar>
</div>
</div>
</template>
<script>
export default {
name: "TreeTest",
data() {
return {
"treeData": {
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人事"
}
]
},
// }
// ,
horizontal: false, //横版 竖版
collapsable: false,
expandAll: true, //是否全部展开
labelClassName: '白色', // 默认颜色
scrollTreeStyle: 'width:100%;',
}
},
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);
}
},
getList() {
// 后台回去的数据 赋值给data即可
},
// 自定义您的点击事件
onNodeClick(e, data) {
alert("点击")
},
expandChange() {
this.collapsable = true
this.toggleExpand(this.data, this.expandAll)
},
selectChange(){
}
}
}
</script>
<!--<style scoped>-->
<!--</style>-->
<style lang="less">
.bg-white {
background-color: white;
}
.bg-orange {
background-color: orange;
}
.bg-gold {
background-color: gold;
}
.bg-gray {
background-color: gray;
}
.bg-lightpink {
background-color: lightpink;
}
.bg-chocolate {
background-color: chocolate;
}
.bg-tomato {
background-color: tomato;
}
//.org-tree-node-label-inner {
// color: #fff;
// background-color: orange;
//}
.el-org-tree {
.el-scrollbar__wrap {
overflow-x: hidden;
}
.org-tree-node-label {
white-space: nowrap;
}
.el-tree-node__content{
background: white;
}
.org-tree-node-label .org-tree-node-label-inner {
padding-top: 8px;
padding-right: 10px;
padding-bottom: 5px;
padding-left: 10px;
cursor: pointer;
}
.horizontal .org-tree-node.is-leaf {
padding-top: 5px;
padding-bottom: 5px;
}
}
</style>
样式配置:
horizontal 组织结构图的排列方式,水平还是竖直,值为true 或 false
collapsable 折叠效果,值为true 或 false
label-class-name 修改背景色,支持自定义类名
render-content 定义如何渲染 node 标签,绑定的 renderContent 是函数
on-expand 定义折叠的组织结构如何展开,该函数参数必须传两个,第一个是 e ,第二个是 data
on-node-click 定义当前节点被点击时执行的方法
需要修改label名称
:render-content="renderContent" //这个属性
renderContent(h, data) { return data.taskName },
注意:
注意:在style中引入样式,必须引入 引入全局样式: lang的值是less 样式
如下,否则展开收缩按钮显示不出来,可以通过上面方法安装,或者下载less文件引用。
<style lang="less">
@import '../libs/org-tree.less';
</style>
https://gitee.com/hukaicode/vue-org-tree/tree/master/src/styles
可以根据实际项目需要进行修改。
爱生活、爱编程!