- 开始时间:2019-04-08
- 目标主要版本:3.x
- 引用 issue:N/A
- 实现的 PR:N/A
摘要
函数式组件必须写成普通函数
{ functional: true }被移除<temple functional>不再被支持
异步组件现在必须通过专门的 API 创建
基本范例
import { h } from 'vue'const FunctionalComp = props => {return h('div', `Hello! ${props.name}`)}
import { defineAsyncComponent } from 'vue'const AsyncComp = defineAsyncComponent(() => import('./Foo.vue'))
动机
简化函数式组件
在 2.x 版本,必须使用一下格式创建函数式组件。
const FunctionalComp = {functional: true,render(h) {return h('div', `Hello! ${props.name}`)}}
这会有如下几个问题:
- 即使组件除了渲染函数其他什么都不需要,它仍然需要使用
functional: true的对象。 - 有些选项是被支持的(如 props 和 inject),但其他选项不被支持(如 components)。然而,用户期望所有其他选项都会支持,因为它看起来和普通有状态组件非常相似(特别是当他们使用带有
<templete functional>的 SFC 时)。
问题的另一方面是,我们注意到一些用户完全(solely)是出于性能的考虑而使用函数式组件,例如,在带有 <templet functional> 的 SFC 的中,还会要求我们在函数式组件中支持更多状态组件选项。然而,我不认为这是我们应该投入更多时间的事情。
在 v3 中,在状态组件和函数式组件在性能差异已经大大降低(drastically reduced),并且在大多数情况下都是微不足道的。因此不再有强烈的动机为了性能而使用功能组件,这也不再是为了支持 <template functional> 的而要付出维护成本的理由。v3 中的函数式组件主要是为了简单,而不是性能。
具体设计
在 3.x 中,我们打算只支持作为普通函数的函数式组件:
import { h } from 'vue'const FunctionalComp = (props, { slots, attrs, emit }) => {return h('div', `Hello! ${props.name}`)}
functional选项被移除,也不再长久支持{ functional: true }的对象格式。- SFC 将不再长久支持
,如果你需要比函数更多的东西,只需要使用普通组件。 - 函数签名也会有变化:
h现在是全局导入;- 该函数接收两个参数:props 和一个暴露了 slot、attrs 和 emit 的上下文对象。这些相当于有状态组件上的有 $ 前缀的东西。
与旧语法的比较
新的函数参数应该提供完全取代 2.x 函数式渲染上下文的能力:
props和slots有同等的价值。data和children不再需要了(只需要props和slots)。listeners将被包含在 attrs 中。injections可以被新的injectAPI(Composition API 的一部分)替代: ```javascript import { inject } from ‘vue’ import { themeSymbol } from ‘./ThemeProvider’
const FunctionalComp = props => {
const theme = inject(themeSymbol)
return h(‘div’, Using theme ${theme})
}
- parent 访问将会被移除。这是一些内部用例的逃生舱 —— 在用户代码中,`props` 和 `injections` 应该是首选。<a name="m7A5C"></a>## Props 选项的声明为了便于在简单的情况下使用,3.x 的函数式组件不需要申明 prop。```javascriptconst Foo = props => h('div', props.msg)
<Foo msg="hello!" />
在没有明确的 props 申明情况下,第一个 props 参数将包含父类传递给该组件的所有内容。
显式的 props 声明
要添加显式的 props 声明,请将 props 附加到函数本身:
const FunctionalComp = props => {return h('div', `Hello! ${props.name}`)}FunctionalComp.props = {name: String}
创建异步组件
新的异步组件 API 在它自己的专用 RFC 中讨论。
缺点
- 迁移成本
备选方案
N/A
采纳策略
- 对于函数式组件,可以提供一个兼容模式,用于一次性的迁移。
- 使用 的 SFCs 应该转换为正常的 SFC。
