基于vue2 封装树形下拉组件
因为项目中的时vant2UI组件库,项目需求中需要实现下拉组织架构功能,翻看vant2文档没有相关的符合的组件,用vue的递归组件实现一个简易的下拉选择框。
采用了递归组件的思路,通过事件每一层子组件触发上一层父组件的事件。
效果图
具体代码实现如下:
tree.vue
<template>
<div>
<div class="treeTest">
<childrenItem @CommuEvent="CommuEventFn" v-for="item in treeList" :key="item.id" :list="item" ></childrenItem>
</div>
</div>
</template>
<script>
import childrenItem from "@/components/childrenItem.vue";
export default {
components: {
childrenItem
},
data() {
return {
isShow: true,
treeList: [
{
id: "1",
label: "菜单管理1",
children: [
{
id: "1-1",
label: "二级菜单1-1",
},
{
id: "1-2",
label: "二级菜单1-2 ",
children: [
{
id: "1-2-1",
label: "三级菜单1-2-1"
}
]
},
{
id: "1-3",
label: "二级菜单 1-3"
},
{
id: "1-4",
label: "二级菜单 1-4"
},
{
id: "1-5",
label: "二级菜单 1-4"
}
]
},
{
id: "2",
label: "员工管理",
children: [
{
id: "2-1",
label: "二级员工2-1"
},
{
id: "2-2",
label: "二级员工2-2"
},
{
id: "2-3",
label: "二级员工2-3"
},
{
id: "2-4",
label: "二级员工2-4",
children: [
{
id: "2-4-1",
label: "三级员工"
}
]
}
]
}
]
};
},
methods:{
active() {
console.log("触发");
this.isShow = !this.isShow;
},
CommuEventFn(id){
console.log('91',id);
}
}
};
</script>
<style lang="less" scoped>
.treeTest {
margin: 50px auto;
padding: 20px;
// background-color: pink;
height: 50vh;
.father {
.fatherItem {
// background-color: aqua;
min-height: 40px;
.title {
// background-color: aqua;
font-size: 20px;
line-height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
}
.children {
margin-left: 20px;
.title {
display: flex;
justify-content: space-between;
align-items: center;
}
}
}
}
}
</style>
childrenItem.vue
<template>
<div class="container">
<ul class="children">
<li class="sonItem" >
<div class="title">
<span @click="selectHandel(list.id)">{{list.label}}</span>
<van-icon v-show="list.children && !isshow" name="arrow" @click="active" />
<van-icon v-show="list.children && isshow" @click="active" name="arrow-down" />
</div>
<div class="childrenItem" v-show="isshow">
<childrenItem @CommuEvent="selectHandel" v-for="item in list.children" :key="item.id" :list="item"></childrenItem>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name:'childrenItem',
props: {
list: {
type: Object,
required: true
}
},
data() {
return {
isshow: true
};
},
methods: {
selectHandel(id) {
// console.log(id);
this.$emit('CommuEvent',id)
},
active() {
console.log("触发");
this.isshow = !this.isshow;
}
}
};
</script>
<style lang="less" scoped>
.children {
margin-left: 20px;
.title {
display: flex;
justify-content: space-between;
align-items: center;
}
}
</style>