對變化的總體概述:
- 在 3.x 中,2.x 帶來的函數式組件的性能提升可以忽略不計,因此我們建議只使用有狀態的組件
- 函數式組件只能由接收
props
和context
(即:slots
、attrs
、emit
) 的普通函數創建 - 非兼容:
functional
attribute 已從單文件組件 (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上