vue利用递归实现无限级伸缩树状菜单

先上效果:

vue利用递归实现无限级伸缩树状菜单_第1张图片

容器:

<template>
  <div>
    <Tree :treeData="treeData"></Tree>
  </div>
</template>

<script>
  import Tree from './tree'
  export default {
    name:'home',
    components:{Tree},
    data() {
      return {
        treeData:[
          {
            "id":11,
            "name":"大标题一",
            "children":[
              {
                "id":1,
                "name":"标题二a",
              },
              {
                "id":3,
                "name":"标题二b",
              },
              {
                "id":4,
                "name":"标题二c",
                "children":[
                  {
                    "id":5,
                    "name":"标题三",
                    "children":[
                      {
                        "id":6,
                        "name":"标题四",
                        "children":[
                          {
                            "id":7,
                            "name":"标题五",
                            "children":[
                              {
                                "id":8,
                                "name":"标题五a",
                              },
                              {
                                "id":9,
                                "name":"标题五b",
                              }
                            ],

                          }
                        ],

                      }
                    ],

                  }
                ],
              }
            ],
          }
        ]
      };
    }
  };
</script>

tree:

<template>
    <div>
        <div v-for="(item,index) in treeData" :key="item.id">
            <div class="child">
                <p @click="changeStaus(index)" :class="isOpen(item)">{{item.name}}</p>
                <Tree v-if="openStatus[index]" :treeData="item.children"></Tree>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        name:'Tree',
        props:['treeData'],
        data() {
            return {
                haveChildren: [],
                openStatus: []
            };
        },
        computed:{
            isOpen(){
                return function(item) {
                    if(item.status&&item.children){
                        return 'text-red'
                    }
                    if(!item.children){
                        return ''
                    }
                    if(!item.status){
                        return 'text'
                    }
                }
            }
        },
        mounted(){
            this.getStatus()
        },
        watch:{
            treeData(){
                this.getStatus()
            }
        },
        methods: {
            // 判断展开收起状态
            changeStaus(index){
                this.treeData[index].status = !this.treeData[index].status
                // 如果展开,就收起
                if(this.openStatus[index]==true){
                    this.$set(this.openStatus,index,false)
                }else{
                    // 根据是否有children来判断是否能展开
                    this.$set(this.openStatus,index,this.haveChildren[index])
                }
            },
            //判断是否有children
            getStatus(){
                if(this.treeData){
                    this.treeData.map((item,index)=>{
                        item.status = false
                        this.openStatus[index] = false
                        if('children' in item){
                            this.haveChildren[index] = true
                        }else{
                            this.haveChildren[index] = false
                        }
                    })
                }
            }
        }
    };
</script>


<style>
    .text-red{
        color: red;
    }
    .text-red:before{
        content:'-';
        position: absolute;
        left:-15px;
    }
    .text:before{
        content:'+';
        position: absolute;
        left:-15px;
    }
    .child{
        position: relative;
        left: 10px;
    }
</style>


你可能感兴趣的:(笔记)