vue—递归组件(vue组件name的作用之一)
相信我们对递归不陌生,因为它是算法中很常见解决问题的思想。而在这里我先强调一点,递归最重要的是什么?终止条件,一个递归不能没有终止条件。
有时候我们在项目中,可能会遇一种需求,它要求我们把很深层嵌套的json数据渲染到页面中,比如文件目录结构。现在我们就把一个文件夹下的所有文件模拟渲染到页面中。
文件目录的树形结构:
为什么要使用递归?
可能有人会有疑惑,我们为什么要使用递归,使用多个v-for嵌套渲染数据不行吗?
首先我们要搞清楚这几点:
- 数据是灵活的,我们并不知道它嵌套有多少层
- 如果数据特别庞大,我们需要写多少代码呢?
所以,想要解决以上问题,在vue中使用递归组件无疑是一种很好的选择
vue递归组件
前边对需求分析了很多,那到底什么是递归组件,说白了我们可以把组件当作函数,在组件内部自己调用自己就行了。我们完全可以把它当成使用递归遍历树结构。
1. 首先我们先看一下我们的数据吧
files: {
title: "我的文件",
children: [{
{
title: "学习",
children: [
{
title: "大学英语"
},{
title: "高等数学"
},{
title: "计算机",
children: [{
title: "计算机操作系统"
},{
title: "计算机网络"
},{
title: "计算机组成原理"
}
]
}
}]
}
这里我没有放太多,看一下格式和结构就行了。我们就是要把这些深层嵌套的数据渲染到页面中。
2. 主函数(主组件)
我们就像递归程序一样,首先需要注册一个主组件,在主组件中存放数据,调用递归组件,并将数据传递给需要递归的子组件。
<template>
<ul id="main"> // 将子组件写进ul内是因为子组件根元素是li
<tree :files="files"></tree> // files就是我们的数据
</ul>
</template>
将子组件写进ul内是因为子组件根元素是li
files就是我们的数据
3. 递归函数(子组件)
<template>
<li v-if="files"> // 因为需要递归,根元素必须是li
<section @click="openFile"> // openFile点击方法
<span>{{files.title}}</span> // 文件标题
<span class="files-mark" v-if="isShow && files.children">-</span>
<span class="files-mark" v-else-if="files.children">+</span> // 展开图标显示
</section>
<ul v-if="isShow"> // 重点!! isshow数据作用是判断是否展开文件,通过openFile方法改变
<tree v-for="(item, index) in files.children" :key="index" :files="item"> //这里的v-for循环遍历的子文件数据,递归调用自身,同时他也是终止条件,如果files.children不存在,就不会调用自身 :files="item"传递参数
</tree>
</ul>
</li>
</template>
- 因为需要递归,根元素必须是li
- 这里的v-for循环遍历的子文件数据,递归调用自身
- 同时v-for也是终止条件,如果files.children不存在,v-for循环截至,就不会调用自身
- :files="item"传递参数给下一层组件
递归组件大致结构和原理就是这样,最后还有一个很重要的细节
子组件一定要有name属性!,递归调用自身是通过name属性,当作组件标签名字调用的,如果没有这个属性,无法调用自身。而且最好将name属性首字母大写。
export default {
name: "Tree", // 关键点
data() {
return {
isShow: false // 控制是否展开
}
},
methods: {
openFile(){
this.isShow = !this.isShow; // 展开或者关闭
}
},
props: { // 接受父组件传递的参数
files: {
type: Object,
required: true
}
}
}
版权声明:本文为qq_42586895原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。