功能组件 重大变更
概述
就变更而言,从高层次来看
- 功能组件在 3.x 中的性能提升与 2.x 相比已微不足道,因此我们建议直接使用有状态组件
- 功能组件只能使用接收
props
和context
(即slots
、attrs
、emit
)的普通函数创建 - 重大变更:
functional
属性在单文件组件 (SFC)<template>
上已移除 - 重大变更:
{ functional: true }
选项在由函数创建的组件中已移除
有关更多信息,请继续阅读!
简介
在 Vue 2 中,功能组件有两个主要用例
- 作为性能优化,因为它们比有状态组件初始化得快得多
- 返回多个根节点
但是,在 Vue 3 中,有状态组件的性能已得到提升,以至于差异微不足道。此外,有状态组件现在还包括返回多个根节点的能力。
因此,功能组件的唯一剩余用例是简单组件,例如用于创建动态标题的组件。否则,建议像往常一样使用有状态组件。
2.x 语法
使用 <dynamic-heading>
组件,该组件负责渲染出适当的标题(即 h1
、h2
、h3
等),这可以在 2.x 中作为单文件组件编写为
js
// Vue 2 Functional Component Example
export default {
functional: true,
props: ['level'],
render(h, { props, data, children }) {
return h(`h${props.level}`, data, children)
}
}
或者,对于那些更喜欢单文件组件中的 <template>
的人
vue
<!-- Vue 2 Functional Component Example with <template> -->
<template functional>
<component
:is="`h${props.level}`"
v-bind="attrs"
v-on="listeners"
/>
</template>
<script>
export default {
props: ['level']
}
</script>
3.x 语法
由函数创建的组件
现在在 Vue 3 中,所有功能组件都是使用普通函数创建的。换句话说,无需定义 { functional: true }
组件选项。
它们将接收两个参数:props
和 context
。context
参数是一个包含组件的 attrs
、slots
和 emit
属性的对象。
此外,与在 render
函数中隐式提供 h
不同,h
现在是全局导入的。
使用前面提到的 <dynamic-heading>
组件示例,以下是它现在的外观。
js
import { h } from 'vue'
const DynamicHeading = (props, context) => {
return h(`h${props.level}`, context.attrs, context.slots)
}
DynamicHeading.props = ['level']
export default DynamicHeading
单文件组件 (SFC)
在 3.x 中,有状态组件和功能组件之间的性能差异已大幅减少,在大多数用例中将微不足道。因此,使用 functional
在 SFC 上的开发人员的迁移路径是移除属性并将所有对 props
的引用重命名为 $props
,并将所有对 attrs
的引用重命名为 $attrs
。
使用我们之前提到的 <dynamic-heading>
示例,以下是它现在的外观。
vue
<template>
<component
v-bind:is="`h${$props.level}`"
v-bind="$attrs"
/>
</template>
<script>
export default {
props: ['level']
}
</script>
主要区别在于
functional
属性已从<template>
上移除listeners
现在作为$attrs
的一部分传递,可以移除
下一步
有关新功能组件的用法以及对渲染函数的总体变更的更多信息,请参阅