什么是函數(shù)式組件?
函數(shù)式組件就是函數(shù)是組件,組件是函數(shù),它的特征是沒有內(nèi)部狀態(tài)、沒有生命周期鉤子函數(shù)、沒有this(不需要實(shí)例化的組件)。
在日常開發(fā)中,我們經(jīng)常會(huì)開發(fā)一些純展示性的業(yè)務(wù)組件,比如一些詳情頁面,列表界面等,它們有一個(gè)共同的特點(diǎn)是:
只要你傳入數(shù)據(jù),我就進(jìn)行展現(xiàn)。
不需要有內(nèi)部狀態(tài),不需要在生命周期鉤子函數(shù)里面做處理。
這時(shí)候你就可以用函數(shù)式組件。
本文只以2.6版本為例說明。
官方文檔
https://cn.vuejs.org/v2/guide/render-function.html#函數(shù)式組件
官方手冊(cè)寫的跟屎一樣。網(wǎng)上的大部分相關(guān)教程只是把手冊(cè)抄一遍,也跟屎一樣。所以我要寫下這篇。
為什么要用它
函數(shù)式組件不需要實(shí)例化,無狀態(tài),沒有生命周期,所以渲染性能要好于普通組件
函數(shù)式組件結(jié)構(gòu)更簡單,代碼結(jié)構(gòu)更清晰
函數(shù)式組件與普通組件的區(qū)別
函數(shù)式組件需要在聲明組件是指定
functional。函數(shù)式組件不需要實(shí)例化,所以沒有
this,this通過render函數(shù)的第二個(gè)參數(shù)來代替。函數(shù)式組件沒有生命周期鉤子函數(shù),不能使用計(jì)算屬性,
watch等等。函數(shù)式組件不能通過
$emit對(duì)外暴露事件,調(diào)用事件只能通過context.listeners.click的方式調(diào)用外部傳入的事件。因?yàn)楹瘮?shù)式組件是沒有實(shí)例化的,所以在外部通過
ref去引用組件時(shí),實(shí)際引用的是HTMLElement。函數(shù)式組件的
props可以只聲明一部分或者全都不聲明,所有沒有在props里面聲明的屬性都會(huì)被自動(dòng)隱式解析為prop,而普通組件所有未聲明的屬性都被解析到$attrs里面,并自動(dòng)掛載到組件根元素上面(可以通過inheritAttrs屬性禁止)。
使用場景
上面已經(jīng)反復(fù)強(qiáng)調(diào),凡是不需要實(shí)例化,無狀態(tài),沒有生命周期的組件,除了props之外沒有別的配置項(xiàng),都可以改寫成函數(shù)式組件。
函數(shù)式組件寫法一:模板語法寫法
父組件:
<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>部分。是不是很簡單?
函數(shù)式組件寫法二:JSX寫法
<script>
export default {
functional: true,
props: {
text: {
type: String
}
},
/**
* 渲染函數(shù)
* @param {*} h
* @param {*} context 函數(shù)式組件沒有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>
注意事項(xiàng):
無需寫
<template functional>...</template>部分,直接缺省。render函數(shù)中遵守JSX寫法,
<p>{props.text}</p>、<p>哈哈嗝</p>是JS一樣的短路關(guān)系,不是代碼疊加關(guān)系。不要給
<p>{props.text}</p>、<p>哈哈嗝</p>加引號(hào)!
由于函數(shù)式組件沒有this,所以props、slots等都在context上面掛著,可以打印一下context看看。
JSX需要另外的學(xué)習(xí)成本,如果你愿意的話可以搜索相關(guān)資料學(xué)習(xí)一下。