Vue实现横向展开树组件功能

由于业务需要产品要求实现一个横向展开的树结构看了下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>

以上就是这个功能的代码核心就是通过递归子组件完成树结构的生成

下面看一下实现效果

这个功能实现起来不难,如果写的有问题的地方欢迎各位大佬指正,感谢大家的支持,如果对您有帮助的话欢迎点个赞。
 

我们下期再见~

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值