對變化的總體概述:
- 在 3.x 中,2.x 帶來的函數式組件的性能提升可以忽略不計,因此我們建議只使用有狀態的組件
- 函數式組件只能由接收
props和context(即:slots、attrs、emit) 的普通函數創建 - 非兼容:
functionalattribute 已從單文件組件 (SFC) 的<template>中移除 - 非兼容:
{ functional: true }選項已從通過函數創建的組件中移除
vue2中函數式組件的定義方式
// 基於render的函數式組件
export default {
functional: true,
props: ['level'],
render(h, { props, data, children }) {
return h(`h${props.level}`, data, children)
}
}
<!-- 結合 <template> 的函數式組件示例 -->
<template functional>
<component
:is="`h${props.level}`"
v-bind="attrs"
v-on="listeners"
/>
</template>
<script>
export default {
props: ['level']
}
</script>
在vue3中,所有的函數式組件都是用普通函數創建的
換句話說,不需要定義{functional:true}組件選項,它將接收兩個參數:props和context,context參數是一個對象,包含組件attrs,slots和emit屬性,現在不是在render函數中隱式提供h而是全局寫入h函數
聲明Functional.vue組件(只寫js文件也可以)
Function.vue
<script>
import {h} from 'vue'
// vue3中函數式組件只能使用函數的方式聲明
function head(props,context) {
console.log(context,'context')
return h(`h${props.level}`,context.attrs,context.clots)
}
//對於屬性驗證和聲明可以通過靜態屬性的方式來聲明
head.props=['level']
export default head
</script>
此時我們可以看到輸出的context為

app.vue組件
<template>
<div>
app
<Function level="2">
這是一個動態的元素
</Function>
</div>
</template>
<script>
import Function from "./components/Function.vue"
export default {
components:{
Function
}
}
</script>
此時就可以看到頁面加載為

官方建議,非必要情況上,沒有必要使用函數式組件
如果需要從vue2的<template>函數式組件遷移到vue3中,直接把組件的template上的functional屬性去掉就可以 ,不需要其他額外的操作
<template>
<component
:is="`h${$props.level}`"
v-bind="$attrs"
/>
</template>
<script>
export default {
props:['level']
}
</script>

此時可以看到h2組件渲染到app上
