递归组件是可以在它们⾃⼰模板中调⽤⾃身的组件。
例如,下⾯是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 "@/components/recursion/Node.vue";export default {components: {Node,},data() {return {// 树形结构的数据folder: {name: "vue-study",children: [{ name: "src", children: [{ name: "main.js" }] },{ name: "package.json" },],},};},};</script>
适当添加⼀些缩进
<h3 :style="{'text-indent': indent+'em'}">{{data.name}}</h3>
export default {props: {// 添加⼀个层级属性level: {type: Number,default: 0,},},computed: {indent() {// 缩进两个字的宽度return this.level * 2;},},};
实现Tree组件
Tree组件是典型的递归组件,其他的诸如菜单组件都属于这⼀类,也是相当常⻅的。
实现tree-node组件,recursion/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>
实现tree组件,recursion/Tree.vue
<template><div class="kkb-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>.kkb-tree {text-align: left;}</style>
使用,recursion/index.vue
<template><Tree :data="treeData"></Tree></template><script>import Tree from "@/components/recursion/Tree.vue";export default {data() {return {treeData: [{title: "Web全栈架构师",children: [{title: "Java架构师",},{title: "JS高级",children: [{title: "ES6",},{title: "动效",},],},{title: "Web全栈",children: [{title: "Vue训练营",expand: true,children: [{title: "组件化",},{title: "源码",},{title: "docker部署",},],},{title: "React",children: [{title: "JSX",},{title: "虚拟DOM",},],},{title: "Node",},],},],},],};},components: {Tree,},};</script>
