vue 树形菜单

1.原理

通过定义组件name,如:name:Node ,在template里面直接引用自身 <Node></Node>

2.代码实现

//Node.vue
<template>
  <div>
    <h3>{{ data.name }}</h3>
    <!-- 有条件嵌套 -->
    <Node v-for="n in data.children" :key="n.name" :data="n"> </Node>
  </div>
</template> <script>
export default {
  name: "Node", // name对递归组件是必要的
  props: {
    data: {
      type: Object,
      require: true,
    },
  },
};
</script>

//NodeTest.vue
<template>
  <div><Node :data="folder"></Node></div>
</template> <script>
import Node from "@/Node.vue";
export default {
  components: {
    Node,
  },
  data() {
    return {
      // 树形结构的数据
      folder: {
        name: "vue-study",
        children: [
          { name: "一级文件夹A", children: [{ name: "二级文件夹" }] },
          { name: "一级文件夹B" },
        ],
      },
    };
  },
};
</script>
复制代码

3.树形菜单实现

image.png

//index.vue
<template>
  <Tree :data="treeData"></Tree>
</template>

<script>
import Tree from "@/components/recursion/Tree.vue";
export default {
  data() {
    return {
      treeData: [
        {
          title: "根节点",
          children: [
            {
              title: "一级AAA"
            },
            {
              title: "一级BBBB",
              children: [
                {
                  title: "二级11"
                },
                {
                  title: "二级22"
                }
              ]
            },
            {
              title: "一级CCC",
              children: [
                {
                  title: "二级666",
                  expand: true,
                  children: [
                    {
                      title: "三级111"
                    },
                    {
                      title: "三级222"
                    },
                    {
                      title: "三级333"
                    }
                  ]
                },
                {
                  title: "二级777",
                  children: [
                    {
                      title: "三级888"
                    },
                    {
                      title: "三级999"
                    }
                  ]
                }, 
              ]
            }
          ]
        }
      ]
    };
  },
  components: {
    Tree
  }
};
</script>

//Tree.vue
<template>
  <div class="tree">
    <TreeNode v-for="item in data" :key="item.title" :model="item"></TreeNode>
  </div>
</template>

<script>
import TreeNode from "@/components/recursion/TreeNode.vue";
export default {
  props: {
    data: {
      type: Array,
      required: true
    }
  },
  components: {
    TreeNode
  }
};
</script>

<style scoped>
.tree {
  text-align: left;
}
</style>

//TreeNode.vue
<template>
  <div>
    <div @click="toggle" :style="{paddingLeft: (level-1)+'em'}">
      <label>{{model.title}}</label>      
      <span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
    </div>
    <div v-show="open" v-if="isFolder">
      <tree-node class="item" v-for="model in model.children" 
        :model="model" :key="model.title"
        :level="level + 1"></tree-node>
    </div>
  </div>
</template>

<script>
export default {
  name: "tree-node",
  props: {
    model: Object,
    level: {
      type: Number,
      default: 1
    }
  },
  data: function() {
    return {
      open: false
    };
  },
  computed: {
    isFolder: function() {
      return this.model.children && this.model.children.length;
    }
  },
  methods: {
    toggle: function() {
      if (this.isFolder) {
        this.open = !this.open;
      }
    },
  }
};
</script>

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享