由于业务需要产品要求实现一个横向展开的树结构看了下elementui的组件没有符合我要求的于是只能自己写一个。
要求如下:
1.每一层级最多有四个菜单超过要换行
2.层级没有限制可多可少
3.每个层级的颜色都不一样
直接上代码
//父组件
<template>
<div>
<treeNode :nodeList="list"></treeNode>
</div>
</template>
<srcipt>
import treeNode from "./treeNode";
export default {
data(){
return {
list: [
{
name: 1,
},
{
name: 2,
children: [
{
name: "一",
children: [
{ name: "one" },
{
name: "two",
children: [
{
name: "yi",
children: [
{
name: "a",
},
{
name: "b",
},
{
name: "c",
},
],
},
{
name: "er",
children: [
{
name: "e",
},
{
name: "f",
},
{
name: "g",
},
],
},
{
name: "san",
},
],
},
{ name: "three" },
{ name: "four" },
{ name: "five" },
],
},
{ name: "二" },
{ name: "三" },
],
},
{
name: 3,
},
{
name: 4,
children: [
{
name: "一",
children: [
{
name: "one",
children: [
{
name: "yi",
},
],
},
],
},
{ name: "二" },
{ name: "三" },
],
},
{
name: 5,
},
],
},
{
name: "er",
children: [
{
name: "e",
},
{
name: "f",
},
{
name: "g",
},
],
},
{
name: "san",
},
],
},
{ name: "three" },
{ name: "four"},
{ name: "five"}
],
},
{ name: "二" },
{ name: "三" },
],
},
{
name: 3,
},
{
name: 4,
children: [
{
name: "一",
children: [
{
name: "one",
children: [
{
name: "yi",
},
],
},
],
},
{ name: "二" },
{ name: "三" },
],
},
{
name: 5,
},
],
}
}
}
</srcipt>
<style lang="less" scoped>
</style>
//子组件
<template>
<div class="treeNode">
<div class="tagList" ref="treeNodeList">
<div
v-for="(item, index) in nodeList"
:key="index"
class="tagItem"
ref="tagItem"
>
<div
class="tagName"
@click="showTag(index, item)"
:style="{ backgroundColor: item.bgColor }"
>
{{ item.name }}
</div>
<div v-if="item.children && item.children.length">
<!-- 递归组件自身 -->
<treeNode :nodeList="item.children" v-show="item.isShow"> </treeNode>
</div>
</div>
</div>
<div></div>
</div>
</template>
<script>
export default {
name: "treeNode",
props: ["nodeList"],
data() {
return {};
},
created() {},
mounted() {
this.init();
},
methods: {
//初始化数据给每一层设置层级添加颜色
init() {
this.setLevel(this.nodeList);
this.setColor();
},
//设置颜色
setColor() {
this.nodeList.forEach((item) => {
this.colorChange(item);
});
},
//展开/关闭点击标签
showTag(index, item) {
if (this.nodeList) {
if (!item.isShow) {
this.setTagHeight(index, item);
this.nodeList.forEach((item, i) => {
this.$set(item, "isShow", false);
if (index == i) {
this.$set(item, "isShow", true);
}
});
} else {
item.isShow = false;
}
}
},
//给点击元素以及兄弟元素设置高度
setTagHeight(index, item) {
console.log(item.children);
if (item.children && item.children.length > 0) {
let tagArr = Array.from(this.$refs.tagItem);
tagArr.forEach((item, i) => {
if (index == i) {
item.style.height = "";
} else {
item.style.height = 50 + "px";
}
});
}
},
//遍历数据对不同层级的数据改变背景颜色
colorChange(node) {
if (node.children) {
node.children.forEach((item, i) => {
let b = item.level * 30 < 240 ? item.level * 30 : 240;
let color = `rgb(${240}, ${240 - item.level}, ${240 - b})`;
this.$set(item, "bgColor", color);
this.colorChange(item);
});
}
},
//递归数据给每一层添加层级
setLevel(list, level = 1) {
list.forEach((item) => {
if (item.children) this.setLevel(item.children, level + 1);
this.$set(item, "level", level);
});
return list;
},
},
};
</script>
<style lang="less" scoped>
.treeNode {
width: 650px;
.tagList {
display: flex;
max-width: 650px;
flex-wrap: wrap;
margin-top: 10px;
.tagItem {
width: 150px;
// min-height: 50px;
line-height: 50px;
text-align: center;
margin-right: 10px;
margin-bottom: 10px;
.tagName {
background-color: aquamarine;
}
}
}
}
</style>
以上就是这个功能的代码核心就是通过递归子组件完成树结构的生成
下面看一下实现效果
这个功能实现起来不难,如果写的有问题的地方欢迎各位大佬指正,感谢大家的支持,如果对您有帮助的话欢迎点个赞。
我们下期再见~