Commit 8e002071 authored by liyan's avatar liyan

2023年1月文章

parent 398d1af1
---
title: Vue中的函数式组件
date: 2023/1/16 22:42:20
tags:
- 前端
- Vue
author: 李燕
---
最近在Vue2的深度学习中,接触到一个新概念——函数式组件。话说自己做Vue项目也一年有余了,居然都没用过这个叫做函数式组件的东西,实在有点...所以,决定好好学习了解一下。
<!-- more -->
**一、 函数式组件的定义及写法**
函数式组件是一个没有实例,即没有data、computed、watch,没有this上下文,没有生命周期,不监听任何属性,不管理任何状态,只有props传参的组件。
它的写法和我们常用的组件大致相同,但需需要添加 functional为ture 的声明。
【基本写法】
```js
Vue.component('function-child', {
functional: true,
props: {
opts: {
typeArray,
default: () => {
return []
},
itemClick: {
type: function,
default: null
}
},
render: function (createElement, context) {
}
})
```
与非函数式组件相比,代码中多了两点:
+ 添加了一个functional: true的属性
+ render函数的参数多了一个context,用来作为上下文,弥补缺少的实例,也就是说,组件需要的一切都是通过 context 参数传递,它是一个包括如下字段的对象:
- props:提供所有 prop 的对象
- children:VNode 子节点的数组
- slots:一个函数,返回了包含所有插槽的对象
- scopedSlots:(2.6.0+) 一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽。
- data:传递给组件的整个数据对象
- parent:对父组件的引用
- listeners:(2.3.0+) 一个包含了所有父组件为当前组件注册的事件监听器的对象。
- injections:(2.3.0+) 如果使用了 inject 选项,则该对象包含了应当被注入的 property。
【单文件组件】写法
```js
<template functional>
<div>
<div v-for="item in props.opts" :key="item.value" @click="props.itemClick(item)">
<span>{{item.label}}:</span>
<span>{{item.value}}</span>
</div>
</div>
</template>
```
采用单文件写法时,需要注意以下变动:
+ 在template标签上追加一个funcitonal属性
+ 通过 props属性,父组件传入的props可以被访问到。
+ 因为函数式组件没有this,我们无法访问$emit方法,所以可以使用props中的一个函数进行触发事件。
+ 单文件组件中的script部分就不需要了。
**二、函数式组件的引用**
```js
<template>
<div>
<function-child
:opts="opts" :itemClick="item => (activeItem = item)"
>
</function-child>
</div>
</template>
import FunctionChild from '@/components/FunctionChild.vue'
export default {
components: {
FunctionChild
},
data() {
return {
opts: [{
label: 'label',
value: '0'
}],
activeItem: ''
}
}
}
```
**三、函数式组件的优点**
函数式组件大抵可以被视作一个只接收一些prop并按预期返回某种渲染结果的fc(props) => VNode 函数,但其优点仍然很明显:
+ 因为函数式组件忽略了生命周期、监听等实现逻辑,所以渲染开销很低、执行速度快。
+ 函数式组件结构比较简单,代码结构更清晰
所以,当我们不需要复杂的组件,不需要在生命钩子函数里面做处理,仅仅只需要将外部传入的数据进行展现,比如一些不需要太多逻辑的UI组件、详情页面,就可以考虑用函数式组件。
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment