递归组件是可以在它们⾃⼰模板中调⽤⾃身的组件。
例如,下⾯是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>