对变化的总体概述:
- 在 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上