Vue 树形菜单封装

2019-05-26  本文已影响0人  取个帅气的名字真好
效果图

item.vue

<template>
    <li>
        <span @click="toggle" >
            <span v-if="hasChild" >{{isOpen ? '🌚' : '🌝'}}</span>
            <!-- 末节点 -->
            <span v-if="!hasChild" >🌞</span> 
            {{ data[treeProps.label] }}
        </span>
        <ul v-show="isOpen" v-if="hasChild">
            <tree-item v-for="(item, index) in data[treeProps.children]" :data="item" :key="index" :treeProps="treeProps" ></tree-item>
        </ul>
    </li>
</template>

<script>
export default {
    name: 'TreeItem', //递归组件必须有name
    props: {
        data: {
            type: [Object, Array], //多个可能的类型
            required: true
        },
        // label、children 默认值
      treeProps:{
          type:Object,
          default:()=>({
            children:'children',
            label:'label'
          })
        }
    },
    data() {
        return {
            isOpen: false,
        }
    },
    computed: {
      // 判断当前级别是否还有children
        hasChild() {
            return this.data[this.treeProps.children] && this.data[this.treeProps.children].length
        }
    },
    methods: {
      // 点击子菜单也要判断是否有children,有就展开
        toggle() {
            if(this.hasChild) {
                this.isOpen = !this.isOpen
            }
        }
    }
}
</script>

<style>
ul {
    list-style: none;
    margin: 10px 0;
    padding-left: 20px;
}
li {
      color: #000;
}
li > span {
    cursor: pointer;
    font-size: 14px;
    line-height: 20px;
}
</style>

index.vue

<template>
  <div>
    <ul v-for="(item,index) in data" :key="index">
      <tree-item :data="item" :treeProps="treeProps"></tree-item>
    </ul>
  </div>
</template>

<script>
  import treeItem from './item'
  export default {
    props: {
      data: {
        type: [Object, Array],
        required: true
      },
      treeProps: {
        type: Object,
        default: () => ({
          children: 'children',
          label: 'label'
        })
      }
    },
    components: {
      treeItem
    },
  }
</script>

使用

<template>
  <div id="test">
    <trees :data="treeData" :treeProps="propsxxx"></trees>
  </div>
</template>

<script>
  import trees from "./../test/index";
  export default {
    data() {
      return {
        propsxxx: {
          children: 'children',
          label: 'name'
        },
        treeData: [{
            name: "一级 1",
            children: [{
              name: "二级 1-1",
              children: [{
                name: "三级 1-1-1"
              }]
            }]
          },
          {
            name: "一级 2",
            children: [{
                name: "二级 2-1",
                children: [{
                  name: "三级 2-1-1"
                }]
              },
              {
                name: "二级 2-2",
                children: [{
                  name: "三级 2-2-1"
                }]
              }
            ]
          },
          {
            name: "一级 3",
            children: [{
                name: "二级 3-1",
                children: [{
                  name: "三级 3-1-1"
                }]
              },
              {
                name: "二级 3-2",
                children: [{
                  name: "三级 3-2-1"
                }]
              }
            ]
          }
        ]
      };
    },
    components: {
      trees
    }
  };
</script>

数据递归可以看看我另一篇文章使用递归实现树状菜单

上一篇下一篇

猜你喜欢

热点阅读