vue 自定义树形结构,树形菜单,多选,单选,父子联动,列表渲染

看效果

实现了父子联动,选中项状态的控制 hidden 字段的true和flase,

可能 难点在于css样式的编写,我这用的是弹性盒布局加百分比,
因为业务需求没做过多的开发,只做到了菜单四级的开发,
数据处理用的是递归,
但是标签,我硬是便利四层,
想到用递归的方法递归组件,但是怕出问题,花太多时间,没弄,
业务需求,懂的都懂,能实现就好。

在这里插入图片描述
组件,Tablebox 这就是全部核心代码
用了一个 element 的 el-checkbox 组件

<template>
  <el-card class="contentPagetabel">
    <div class="tablebox">
      <div class="table_box">
        <div v-for="(item,index) in listTip" :key="index" class="div1">
          <span class="span1 spancolor"> {{ item.name }}</span>
          <div class="div2">
            <div v-for="(item1,in1dex) in item.children" :key="in1dex+111" class="div222">
              <span class="span2 spancolor"> {{ item1.name }}</span>
              <div class="div3">
                <div v-for="(item2,index22) in item1.children" :key="index22+222" class="div333">
                  <span class="span3 spancolor"> {{ item2.name }}</span>
                  <div class="div4">
                    <div v-for="(item3,index3) in item2.children" :key="index3+333" class="div4444">
                      <span class="span4 spancolor"> {{ item3.name }}</span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div v-for="(item,index) in tablelist" :key="index+10" class="div1">
          <el-checkbox v-model="item.hidden" class="span1" @change="changeCheckFun(item )"> {{ item.name }}</el-checkbox>
          <div class="div2">
            <div v-for="(item1,in1dex) in item.children" :key="in1dex+111" class="div222">
              <el-checkbox v-model="item1.hidden" class="span2" @change="changeCheckFun(item,item1 )"> {{ item1.name }}</el-checkbox>
              <div class="div3">
                <div v-for="(item2,index2) in item1.children" :key="index2+222" class="div333">
                  <el-checkbox v-model="item2.hidden" class="span3" @change="changeCheckFun(item,item1,item2)"> {{ item2.name }}</el-checkbox>
                  <div class="div4">
                    <div v-for="(item3,index3) in item2.children" :key="index3+333" class="div4444">
                      <el-checkbox v-model="item3.hidden" class="span4" @change="changeCheckFun(item,item1,item2,item3)"> {{ item3.name }}</el-checkbox>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </el-card>

</template>

<script>
export default {
  name: 'Tablebox',
  props: { tablelist: { type: Array, default: () => { return [] } }},
  data() {
    return {
      listTip: [
        {
          name: '一级菜单',
          id: 18256231569,
          children: [
            {
              name: '二级菜单',
              id: 18256231569,
              children: [
                {
                  name: '三级菜单',
                  children: [
                    {
                      name: '按钮权限',
                      id: 18256231569
                    }
                  ],
                  id: 18256231569
                }
              ]
            }
          ]
        }
      ],
      list: []
    }
  },
  methods: {
    // 清空
    resetFun() {
      this.$refs.elForm.resetFields()
      this.getList()
    },
    setHidden(item, booem) {
      if (item.children.length > 0) {
        item.children.forEach(itm => {
          itm.hidden = booem
          if (itm.children.length > 0) {
            itm.children.forEach(itm2 => {
              itm2.hidden = booem
              if (itm2.children.length > 0) {
                itm2.children.forEach(itm3 => {
                  itm3.hidden = booem
                })
              }
            })
          }
        })
      }
    },
    changeCheckFun(item, item1, item2, item3) {
      if (item && item1 === undefined && item2 === undefined && item3 === undefined) {
        if (!item.hidden) {
          this.setHidden(item, false)
        } else {
          this.setHidden(item, true)
        }
      }
      if (item1 && item2 === undefined && item3 === undefined) {
        if (item1.hidden) {
          item.hidden = true
          this.setHidden(item1, true)
        } else {
          this.setHidden(item1, false)
        }
      }
      if (item2 && item3 === undefined) {
        if (item2.hidden) {
          item.hidden = true
          item1.hidden = true
          this.setHidden(item2, true)
        } else {
          this.setHidden(item2, false)
        }
      }
      if (item3) {
        item.hidden = true
        item1.hidden = true
        item2.hidden = true
      }
      this.$emit('change', this.tablelist)
    }
  }
}
</script>

<style lang='scss'>
.contentPagetabel {
  width: 98%;
  height: 80vh;
  margin: auto;
  border-radius: 5px;
  box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.1);
  background-color: #fff;
  padding: 20px 0px;
  box-sizing: border-box;
  overflow-y: scroll;
}
.tablebox{
    height: 100%;
}
.spancolor{
  color:rgb(71, 71, 71) !important;
  text-align: center !important;
  font-size: 17px;
  font-weight: 555;
  justify-content: center;
}
.table_box{
  border: 1px solid #ccc;
  border-bottom: 0px solid #ccc;
  height: 100%;
  overflow-y: scroll;
  border-radius: 5px ;
 .div1{
    display: flex;
    color: #333;
    font-weight: 555;
    justify-content: center;

    .span1{
      display: inline-block;
      color: #999;
      width: 20%;
      border-bottom: 1px solid #ccc;
      border-right: 1px solid #ccc;
      text-align: left;
      padding-left: 30px;
      padding: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .div2{
      display: flex;
      flex-direction: column;
      width: 80%;
      .div222{  display: flex;}
      .span2{
        display: inline-block;
        width: 20%;
        border-right: 1px solid #ccc;
        border-bottom: 1px solid #ccc;
        text-align: left;
        display: flex;
        align-items: center;
        padding-left: 30px;
        padding: 10px;
      }
     .div3{
        display: flex;
         width: 80%;
        flex-direction: column;
        .div333{ display: flex;
          border-bottom: 1px solid #ccc;
        }
        .span3{
          display: inline-block;
          border-right: 1px solid #ccc;
          width: 30%;
          text-align: left;
          align-items: center;
          padding-left: 30px;
          padding: 10px;
        }
        .div4{
           width: 70%;
           justify-content: space-around;
          display: flex;
          align-items: center;
        }
     }
   }
 }
 }
</style>

使用方法
import Tablebox from ‘./Tablebox’
<tablebox :tablelist=“list” @change=“changeList” />

重点在于这个list数组;
因为我是八字段名写死的,不像element里面那样灵活,如果需要,在组件里面改一下参数就好,
下面这个是我测试创建的数据,你可以试一下

 list: [
        {
          name: '甘肃省',
          id: 18256231569,
          hidden: false,
          children: [
            {
              name: '天水市',
              id: 18256231569,
              hidden: false,
              children: [
                {
                  name: '甘谷县',
                  id: 18256231569,
                  hidden: false,
                  children: [
                    {
                      name: '测试2222',
                      hidden: false,
                      children: [],
                      id: 18256231569
                    },
                    {
                      name: '测试2222',
                      hidden: false,
                      children: [],
                      id: 18256231569
                    },
                    {
                      name: '测试2222',
                      hidden: false,
                      children: [],
                      id: 18256231569
                    },
                    {
                      name: '测试2222',
                      hidden: false,
                      children: [],
                      id: 18256231569
                    }
                  ]
                },
                {
                  name: '巫山县巫山县巫山县巫山县',
                  hidden: false,
                  id: 18256231569,
                  children: [
                    {
                      name: '测试2222测试2222测试2222测试2222测试2222',
                      children: [],
                      hidden: false,
                      id: 18256231569
                    }
                  ]
                }
              ]
            },
            {
              name: '兰州市',
              id: 18256231569,
              hidden: false,
              children: [
                {
                  name: '测试2222',
                  children: [],
                  hidden: false,
                  id: 18256231569
                }
              ]
            },
            {
              name: '嘉峪关',
              id: 18256231569,
              hidden: false,
              children: [
                {
                  name: '测试2222',
                  children: [],
                  hidden: false,
                  id: 18256231569
                }
              ]
            }
          ]
        },
        {
          name: '甘肃省',
          id: 18256231569,
          hidden: false,
          children: [
            {
              name: '天水市',
              hidden: false,
              id: 18256231569,
              children: [
                {
                  name: '甘谷县',
                  hidden: false,
                  id: 18256231569,
                  children: [
                    {
                      name: '测试2222',
                      hidden: false,
                      children: [],
                      id: 18256231569
                    },
                    {
                      name: '测试2222',
                      hidden: false,
                      children: [],
                      id: 18256231569
                    },
                    {
                      name: '测试2222',
                      children: [],
                      hidden: false,
                      id: 18256231569
                    },
                    {
                      name: '测试2222',
                      hidden: false,
                      children: [],
                      id: 18256231569
                    }
                  ]
                },
                {
                  name: '巫山县巫山县巫山县巫山县',
                  id: 18256231569,
                  hidden: false,
                  children: [
                    {
                      name: '测试2222测试2222测试2222测试2222测试2222',
                      children: [],
                      hidden: false,
                      id: 18256231569
                    }
                  ]
                }
              ]
            },
            {
              name: '兰州市',
              id: 18256231569,
              hidden: false,
              children: [
                {
                  name: '测试2222',
                  hidden: false,
                  children: [],
                  id: 18256231569
                }
              ]
            },
            {
              name: '嘉峪关',
              id: 18256231569,
              hidden: false,
              children: [
                {
                  name: '测试2222',
                  children: [],
                  hidden: false,
                  id: 18256231569
                }
              ]
            }
          ]
        }
      ],

这个就是获取操作之后数据的方法,
我这边选择与不选择数据的改变字段是hidden值的变化

 changeList(e) {
	console.log(e)
},

OK就这样了,里面问题还有很多,可以说是非常粗糙了,不喜勿喷,谢谢,如果有用,点个赞吧

Logo

前往低代码交流专区

更多推荐