1.使用及安装
下载依赖
npm install @wchbrad/vue-easy-tree
引入俩种方案
1.在main.js中引入
import VueEasyTree from "@wchbrad/vue-easy-tree";
import "@wchbrad/vue-easy-tree/src/assets/index.scss"
Vue.use(VueEasyTree)
2.当前页面引入
import VueEasyTree from "@wchbrad/vue-easy-tree";
import "@wchbrad/vue-easy-tree/src/assets/index.scss"
2.封装vue-easy-tree
<template>
<div class='select-tree-container' ref="selectMutiple">
<el-input
autocomplete="off"
:placeholder="loading?'正在加载数据···':placeholder"
:readonly="true"
:disabled="loading"
:value="checkedTreeData"
>
<i v-show="loading" slot="suffix" class="el-input__icon el-icon-loading"></i>
</el-input>
<transition name="sub-comments">
<div
class="scroll-container"
v-show="selectTreeFlag">
<el-input
placeholder="输入关键字进行过滤"
v-model="filterText"
>
</el-input>
<VueEasyTree
:data="treeData"
show-checkbox
height="500px"
:node-key="treeProps.value"
:props="treeProps"
:default-checked-keys="newArr"
ref="selectMutipleTree"
@check="handleCheck"
:filter-node-method="filterNode"
:check-strictly="checkStrictly">
</VueEasyTree>
</div>
</transition>
</div>
</template>
<script>
import VueEasyTree from "@wchbrad/vue-easy-tree";
// 样式文件,可以根据需要自定义样式或主题
import "@wchbrad/vue-easy-tree/src/assets/index.scss"
import {debounce} from '@/shared/debounceAndtThrottle.js'
export default {
name: 'SelectMutipleTree',
components: {
VueEasyTree
},
props: {
treeData: {
type: Array,
required: true,
default:[],
},
treeProps: {
type: Object,
default: function () {
return {
value: 'id',
label: 'orgName',
checkStrictly: true
}
}
},
checkedTreeData: {
type: String,
required: true
},
placeholder: {
type: String,
default: '请输入'
},
checkStrictly: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: true
},
defaultCheckedKeys:{
type: Array,
default:() => {
return []
},
}
},
data () {
return {
selectTreeFlag: false,
filterText: '',
filterText_:null,
newArr:[]
}
},
watch: {
checkedTreeData: function (newValue) {
if (!newValue) {
this.$nextTick(() => {
this.$refs.selectMutipleTree.setCheckedKeys([])
})
}
},
filterText(val) {
this.filterText_(val)
},
treeData(val){
var num = 0
this.chuli(val,num)
},
defaultCheckedKeys(val){
if(val.length == 0) {
this.newArr =[]
}else{
this.chuliCheckedKeys(this.treeData, val)
}
}
},
methods: {
debounce (callback, delay = 500) {
var t = null;
return function (...args) {
clearTimeout(t);
t = setTimeout(() => callback(...args),delay);
}
},
chuliCheckedKeys(list, val){
list.forEach(item => {
val.forEach(i => {
if(item[this.treeProps.value].split('-')[0] === i){
i= item[this.treeProps.value]
this.newArr.push(i)
}
})
if(item[this.treeProps.children]){
this.chuliCheckedKeys(item[this.treeProps.children], val)
}
})
},
chuli(list,num){
list.forEach(i=>{
num++
i[this.treeProps.value] = i[this.treeProps.value] + "-" + num;
if(i[this.treeProps.children]){
this.chuli(i[this.treeProps.children],num)
}
})
},
handleCheck (checkedNodes, checkedKeys) {
checkedKeys.checkedNodes.forEach((f) => {
f[this.treeProps.value] = f[this.treeProps.value].split('-')[0]
});
this.$emit('handleCheckData', checkedKeys.checkedNodes)
},
filterNode(value, data) {
if (!value) return true;
return data[this.treeProps.label].includes(value);
}
},
created () {
},
mounted () {
if (!this.checkedTreeData) {
this.$nextTick(() => {
this.$refs.selectMutipleTree.setCheckedKeys([])
})
}
this.$refs.selectMutiple && this.$refs.selectMutiple.addEventListener('click', (event) => {
const ev = event || window.event
if (ev.stopPropagation) {
ev.stopPropagation()
} else {
ev.cancelable = true
}
this.selectTreeFlag = !this.loading && true
})
this.$root.$el.addEventListener('click', (event) => {
this.selectTreeFlag = false
})
this.filterText_ = debounce((val)=>this.$refs.selectMutipleTree.filter(val), 1000)
},
destroyed () {
}
}
</script>
<style lang="scss" scoped>
.scroll-container {
max-height: 600px;
overflow-y: auto;
position: absolute;
z-index: 10;
width: 100%;
border: 1px solid #eeeeee;
border-top: none;
background: #ffffff;
::v-deep {
.el-scrollbar__wrap {
overflow-x: hidden;
}
}
}
.sub-comments-leave-active,.sub-comments-enter-active {
transition: max-height 0.1s linear;
}
.sub-comments-enter,.sub-comments-leave-to {
max-height:0 ;
opacity: 0;
}
.sub-comments-enter-to,.sub-comments-leave {
max-height: 136px ;
}
</style>
3.具体页面该如何使用
<select-mutiple-tree size="mini" style="display: inline-block" :treeData="organizationTree" :treeProps="releaseTreeProps" :loading="treeLoading" :checkedTreeData="addCaseForm.copyToUserListName"
placeholder="请选择" @handleCheckData="handleCheck" :checkStrictly="releaseTreeProps.checkStrictly">
</select-mutiple-tree>
1.data中定义
organizationTree: [],
treeLoading: true, //控制人员树加载状态
releaseTreeProps: {
value: "nodeIdAndType",
label: "nodeName",
children: "organizationTreeUserSingeNodeList",
checkStrictly: false,
},
addCaseForm: {
copyToUserListName:'',
copyToUserList:[], //抄送人
}
2.引入及注册
import SelectMutipleTree from "@/components/selectMutipleTree";
components:{SelectMutipleTree }
3.接口中写
接口名字().then((response) => {
const { data, success } = response;
if (success) {
this.organizationTree = data;
this.treeLoading = false;
} else {
this.organizationTree = [];
this.treeLoading = false;
}
}).catch((error) => {
this.organizationTree = [];
this.treeLoading = false;
});
4.方法
handleCheck(checkedData) {
if (checkedData.length > 0) {
// 集合
var namesArr = [];
var idsArr = [];
var userName = [];
checkedData.forEach((f) => {
if (f.nodeType !== 0) {
namesArr.push(f.nodeName);
idsArr.push(f.nodeId)
userName.push({
id: f.nodeId,
name: f.nodeName,
});
}
});
this.addCaseForm.copyToUserListName = namesArr.join(";");
this.addCaseForm.copyToUserList = idsArr;
} else {
this.addCaseForm.copyToUserListName = '';
this.addCaseForm.copyToUserList = [];
}
},
5.具体返回的后台格式