- 递归,在项目中的应用还是很多的,比如导航菜单,一级菜单里面有二级菜单,二级菜单里面有三级菜单。类似于各种树状结构的功能,都会用到递归。vue中组件也可以被用来递归(反复调用组件自身)。
- 函数式组件,也可以作为 Vue 性能优化的一种方式。比如一些静态页面。
先说递归: 如图:假如我们现在要做一个类似多级导航菜单的功能 。
vue组件递归实现过程
下面我们也要写一个多级导航菜单的功能。 假设 parent.vue 组件data中有这样一组数据,
list: [
{
key: "1",
title: "Option 1"
},
{
key: "2",
title: "Navigation 2",
children: [
{
key: "2.1",
title: "Navigation 2.1",
children: [
{
key: "2.1.1",
title: "Option 2.1.1",
}
]
}
]
},
{
key: '3',
title: 'Option 3'
}
]
parent.vue
组件的template中是这样写的:
<ul>
<template v-for="item in list">
<li v-if="!item.children">{{ item.title }}</li>
<li v-else>
<div>{{ item.title }}</div>
<sub-menu :menu-info="item.children" />
</li>
</template>
</ul>
注:
- 上面使用了
<sub-menu />
组件。首先需要在 script 中 import 这个组件,再注册组件。 :menu-info
,将需要递归的数据以属性传参的形式传递给需要递归的组件。
sub-menu.vue
组件代码如下:
<template>
<ul>
<template v-for="item in menuInfo">
<li v-if="!item.children">{{ item.title }}</li>
<li v-else>
<div>{{ item.title }}</div>
<sub-menu :menu-info="item.children" />
</li>
</template>
</ul>
</template>
<script>
export default {
name: 'SubMenu',
props: ['menuInfo']
};
注:
props
接收父组件传递过来数据。<sub-menu :menu-info="item.children" />
递归当前组件。并传参。
注意:
- 被递归的组件必须有 name 选项,然后使用 name 选项的值作为组件名来递归当前组件。
- 递归当前组件的时候,必须接收需要被递归的数据。
最后效果如下:
单文件组件
上面的 SubMenu.vue 组件是通过单文件组件的方式写的,打印这个组件实例,会有 render,data,以及生命周期函数等等 完整的vue组件的属性。
函数式单文件组件
下面是函数式组件打印的组件实例。
没有管理任何状态,也没有监听任何传递给它的状态,也没有生命周期方法。实际上,它只是一个接受一些 prop 的函数。在这样的场景下,我们可以将组件标记为 functional
,这意味它无状态 (没有响应式数据),也没有实例 (没有 this
上下文)。这种组件就是函数式组件。因为函数式组件只是函数,所以渲染开销也低很多。
在 2.5.0 及以上版本中,如果你使用了单文件组件,那么基于模板的函数式组件可以这样声明:
<template functional> </template>
下面我们用函数式组件改写上面的 SubMenu.vue 组件。
<template functional>
<ul>
<template v-for="item in props.menuInfo">
<li v-if="!item.children">{{ item.title }}</li>
<li v-else>
<div>{{ item.title }}</div>
<sub-menu :menu-info="item.children" />
</li>
</template>
</ul>
</template>
<script>
export default {
name: 'SubMenu',
props: ['menuInfo']
};
因为没有 this, 所有必须使用 props.xx 的形式获取传递过来的参数。
总结 :
-
递归组件
- 父组件以props形式给被递归的组件传递参数
- 被递归的组件,以 props 形式接收
- 被递归的组件,还需要 name 选项
- 被递归的组件,当需要递归的情况下,则用当前组件的 name 选项值,作为被递归的组件名,并以 prop 形式传递参数给递归组件。
-
函数式单文件组件
- 给
template
赋上一个functional
属性即可 - 单文件组件里面不能包含 data,生命周期等钩子,也不能使用 this 等 上下文。
- 因为没有 this ,所以获取 props里面的值,使用 props.xx 形式获取。
- 函数式组件,也可以作为 Vue 性能优化的一种方式。比如一些静态页面。
- 给