vue 递归组件 + 无限树状列表

白开水
1 评论
/ /
996 阅读
/
3742 字
24 2023-02

需求:需要展示树状,可以无限添加子目录

1创建父组件

<template>
  <div>
    <my-trees :list="list" :key="codeNum"></my-trees>
  </div>
</template>
<script>
import myTrees from "./child";
export default {
  components: {
    myTrees,
  },
  provide() {
    return {
      //刷新数据
      newFoo: this.detail,
    };
  },
  data() {
    return {
      list: [],
      codeNum:1,
    };
  },
  // computed:{
  //   //数据处理成树形
  //       treeData(){
  //         let cloneData = JSON.parse(JSON.stringify(this.catalogList))
  //         // let cloneData2 = JSON.parse(JSON.stringify(this.data))
  //         // 对源数据深度克隆
  //         return cloneData.filter(father=>{
  //           let branchArr = cloneData.filter(child=>father.catalogId == child.catalogParent)    //返回每一项的子级数组
  //           branchArr.length>0 ? father.children = branchArr : ''   //如果存在子级,则给父级添加一个children属性,并赋值
  //           return father.catalogParent==null;      //返回第一层
  //         });
  //       }
  //     },
  mounted () {
      this.detail()
  },
  methods: {
    //获取最新数据
    detail() {
      this.list = [
        {
          name: "白开水111111111",
          cList: [
            { name: "二级白开水" },
            {
              name: "one chicken",
              cList: [
                { name: "三级白开水3333", cList: [{ name: "四级白开水" }] },
              ],
            },
          ],
        },
        { name: "2222222222" },
        {
          name: "白开水33333333",
          cList: [{ name: "二级白开水" }, { name: "one chicken" }],
        },
      ];
      //首次加载到父页面只能循环子组件儿组件,需要再刷新一次子组件才会显示孙组件
    //   if (this.codeNum == 1) {
    //         var rand = Math.random();
    //         this.codeNum = rand;
    //         // console.log("第一次加载调用两次");
    //       } else {
    //         // console.log("第n次加载则不用");
    //       }
    },
  },
};
</script>
<style scoped>


</style>

 2树状子组件 <template> <ul class="one"> <li v-for="(item,index) in list " :key="index"> <p>{{item.name}}</p> <tree-menus :list="item.cList" class="open"></tree-menus> </li> </ul> </template>

<script>
export default {
  name: "treeMenus",
  props: {
    list: Array,
  },
  //由于vue有$parent属性可以让子组件访问父组件。但孙组件想要访问祖先组件就比较困难。
  inject: ["newFoo"],
  methods: {
    click() {
        //操作事件后直接刷新父组件更新数据
        this.newFoo();
    },
  },
};
</script>

 <style>
ul {
  padding-left: 20px !important;
  list-style: none;
  text-align: left;
  border: 1px solid rgb(166, 184, 207);
}
ul li{
  border: 1px solid rgb(166, 184, 207);
}
.open {
    padding-left: 20px;
    background-color: antiquewhite;
}
</style>

要素:

1 子组件需要调用父组件刷新操作后的数据,并且因为自组件内会循环组组件,会有孙组件以及更孙组件的情况,因为没用bus,这里用通过provide/inject可以调用祖先组件的数据

2 关于树状数据,因为后端有时候不会给你配好的树状数据,如果是返回的一元数组,类似

{id:1,parentId:0,name:"一级菜单A",rank:1},
{id:2,parentId:0,name:"一级菜单B",rank:1},
{id:3,parentId:0,name:"一级菜单C",rank:1},
{id:4,parentId:1,name:"二级菜单A-A",rank:2},
{id:5,parentId:1,name:"二级菜单A-B",rank:2},

可以直接用上面父组件的treeData即可转换

3 关于首次加载子组件加载完成孙组件还需调用第二次的问题,可以在调用数据方法里添加随机数实现二次加载.

  • 测试

    测试