开始
在js/jsx中,我们可以通过递归的方式来生成一些有规律的dom结构,那么,在Vue模板中,我们能不能递归生成dom呢?答案是肯定的。在Vue中,组件可以递归的调用自己本身,但是有一些条件:
该组件要有name属性
要确保递归的调用有终止条件,防止内存溢出
Demo
下面为了方便理解递归组件,我写了一个小的demo:
有这么一份数据,我们希望能把它做成像文件树一样的结果
[
{
'name': 'Vue',
'children': [
{
'name': '模板语法'
},
{
'name': '计算属性'
},
{
'name': '生命周期',
'children': [
{
'name': 'beforeCreate'
},
{
'name': 'created'
},
{
'name': 'beforeMount'
},
{
'name': 'mounted'
},
{
'name': 'beforeUpdate'
},
{
'name': 'updated'
},
{
'name': 'beforeDestroy'
},
{
'name': 'destroyed'
}
]
}
]
},
{
'name': 'React',
'children': [
{
'name': 'jsx'
},
{
'name': '生命周期'
}
]
},
{
'name': 'Angular'
}
]
先写我们的树组件Tree.vue
{{ data.name }}
export default {
name: 'TreeMenu',
props: {
data: {
type: Object,
required: true
}
},
data() {
return {
open: false
}
},
computed: {
hasChild() {
return this.data.children && this.data.children.length
}
},
methods: {
toggle() {
if(this.hasChild) {
this.open = !this.open
}
}
}
}
ul {
list-style: none;
margin: 10px 0;
}
li {
padding: 3px 0;
}
li > span {
cursor: pointer;
font-size: 14px;
line-height: 20px;
}
i.icon {
display: inline-block;
width: 20px;
height: 20px;
margin-right: 5px;
background-repeat: no-repeat;
vertical-align: middle;
}
.icon.folder {
background-image: url("../assets/images/folder.svg");
}
.icon.folder-open {
background-image: url("../assets/images/folder-open.svg");
}
.icon.file-text {
background-image: url("../assets/images/file.svg");
}
.tree-menu li {
line-height: 1.5;
}
可以看到,我们在Tree组件中有个name选项,值为TreeMenu,然后组件内部调用TreeMenu本身,通过v-for来进行递归条件的判断,这就形成了一个递归组件
然后我们在外部App.vue调用Tree组件
var myData = [
{
'name': 'Vue',
'children': [{
'name': '模板语法'
},
{
'name': '计算属性'
},
{
'name': '生命周期',
'children': [
{
'name': 'beforeCreate'
},
{
'name': 'created'
},
{
'name': 'beforeMount'
},
{
'name': 'mounted'
},
{
'name': 'beforeUpdate'
},
{
'name': 'updated'
},
{
'name': 'beforeDestroy'
},
{
'name': 'destroyed'
}
]
}
]
},
{
'name': 'React',
'children': [{
'name': 'jsx'
},
{
'name': '生命周期',
'children': []
}
]
},
{
'name': 'Angular'
}
];
import MyTree from './components/Tree'
export default {
components: {
MyTree
},
data() {
return {
data: myData
}
}
}
最终效果如图:
结束
虽然这篇博客看起来很简单,只是一个小的知识点,但是Vue的递归组件确实是一个非常强大的功能。可以用来实现一些类似文件树、部门树、级联选择这样的组件,在实际业务开发中这些组件也经常用到,还是非常重要的~