什么是函数式组件?
函数式组件就是函数是组件,组件是函数,它的特征是没有内部状态、没有生命周期钩子函数、没有this(不需要实例化的组件)。
在日常开发中,我们经常会开发一些纯展示性的业务组件,比如一些详情页面,列表界面等,它们有一个共同的特点是:
只要你传入数据,我就进行展现。
不需要有内部状态,不需要在生命周期钩子函数里面做处理。
这时候你就可以用函数式组件。
本文只以2.6版本为例说明。
官方文档
https://cn.vuejs.org/v2/guide/render-function.html#函数式组件
官方手册写的跟屎一样。网上的大部分相关教程只是把手册抄一遍,也跟屎一样。所以我要写下这篇。
为什么要用它
函数式组件不需要实例化,无状态,没有生命周期,所以渲染性能要好于普通组件
函数式组件结构更简单,代码结构更清晰
函数式组件与普通组件的区别
函数式组件需要在声明组件是指定
functional
。函数式组件不需要实例化,所以没有
this
,this
通过render
函数的第二个参数来代替。函数式组件没有生命周期钩子函数,不能使用计算属性,
watch
等等。函数式组件不能通过
$emit
对外暴露事件,调用事件只能通过context.listeners.click
的方式调用外部传入的事件。因为函数式组件是没有实例化的,所以在外部通过
ref
去引用组件时,实际引用的是HTMLElement
。函数式组件的
props
可以只声明一部分或者全都不声明,所有没有在props
里面声明的属性都会被自动隐式解析为prop
,而普通组件所有未声明的属性都被解析到$attrs
里面,并自动挂载到组件根元素上面(可以通过inheritAttrs
属性禁止)。
使用场景
上面已经反复强调,凡是不需要实例化,无状态,没有生命周期的组件,除了props
之外没有别的配置项,都可以改写成函数式组件。
函数式组件写法一:模板语法写法
父组件:
<template>
<div>
<func text="aaaaaaaa" />
</div>
</template>
<script>
import func from '@/components/func.vue';
export default {
components: {
func
}
};
</script>
func.vue:
<template functional>
<p>{{props.text ? props.text : '哈哈'}}</p>
</template>
注意,没有<script>...</script>
部分。是不是很简单?
函数式组件写法二:JSX写法
<script>
export default {
functional: true,
props: {
text: {
type: String
}
},
/**
* 渲染函数
* @param {*} h
* @param {*} context 函数式组件没有this, props, slots等都在context上面挂着
*/
render(h, context) {
console.log(context);
const { props } = context
if (props.text) {
return <p>{props.text}</p>
}
return <p>哈哈嗝</p>
}
}
</script>
注意事项:
无需写
<template functional>...</template>
部分,直接缺省。render函数中遵守JSX写法,
<p>{props.text}</p>
、<p>哈哈嗝</p>
是JS一样的短路关系,不是代码叠加关系。不要给
<p>{props.text}</p>
、<p>哈哈嗝</p>
加引号!
由于函数式组件没有this
,所以props
、slots
等都在context
上面挂着,可以打印一下context
看看。
JSX需要另外的学习成本,如果你愿意的话可以搜索相关资料学习一下。