算法学习中,递归和迭代是一对孪生兄弟。下面我们就用递归来完成vue中的组件递归。也将认识到组件的递归,实际上就是数据递归的外在形式。所以我们完成组件的递归,最重要的还是定义好可以递归的数据结构。Here we go.
下面我们在VueJS里创建一个递归树组件,完整的Demo请戳这里
创建一个树组件
树组件的结构可以想像成文件目录
+ 根目录
+ 目录A
+ 目录A1
+ 目录B
复制代码
可以把文件目录理解成树(Tree
),目录就是树的节点(Node
)。树总是有一个根节点,从根节点上进行某一操作,找到子节点,重复同一操作,直到叶子节点(没有子节点的节点)。
下面我们用label
和children
来表示目录名和子目录:
const tree = {
label: '根目录',
children: [
{
label: '目录A',
children: [
// 叶子节点
{
label: '目录A1'
}
]
}, {
label: '目录B'
}
]
}
复制代码
上面的tree
数据就是我们要创建的Tree
组件要传入的data
,然后TreeNode.vue
组件长下面这样,接收props
,渲染根节点:
<!-- TreeNode.vue -->
<template>
<ul>
<node :node="treeData"></node>
</ul>
</template>
<script>
import Node from './components/Node'
export default {
name: 'tree-node',
props: {
treeData: Object
},
components: {
Node
}
}
</script>
复制代码
TreeNode
组件的主要目的还是创建一个根节点,同时引入treeData
。
定义node节点
一个node节点的结构长下面这样,必需要有一个label属性和可能的children。从数据结构上就可以看出递归的样子了,所以html上的递归归根到底还是数据的递归
{
"label": "",
"children": [
// begin 子节点
{
"label": "",
children: []
}
// end
]
}
复制代码
Node.vue
的详解
可以看到此组件的name
为node
,然后组件里面用到了node
自身,但是不需要在components里显式引用。 这就是组件递归的关键点了
<!-- Node.vue -->
<template>
<li >
<span>{{node.label}}</span>
<ul v-if="node.children && node.children.length">
<!-- 在这里引用node自身,完成递归操作 -->
<node :node="node" v-for="(node, i) of node.children" :key="i"></node>
</ul>
</li>
</template>
<script>
export default {
name: "node",
props: {
node: Object
},
components: {
// 这里不需要引用node自身
}
};
</script>
复制代码
各自归位
最后我们创建一个App.vue
来传递上面定义好的treeData
给TreeNode.vue
组件,App.vue
如下面所示:
<!-- App.vue -->
<template>
<div id="app">
<TreeNode :tree="treeData"></TreeNode>
</div>
</template>
<script>
import TreeNode from "./components/TreeNode";
export default {
name: "App",
data: () => ({
treeData: {
label: "A",
children: [
{
label: "A-1",
children: [
{
label: "A-1-1"
},
{
label: "A-1-2"
}
]
}
]
}
}),
components: {
TreeNode
}
};
</script>
复制代码
结语
好好练习下吧,希望对你理解递归组件有帮助。