1、内容系个人翻译自 Vue 3.0 Beta 版文档中 Migration From Vue 2 章节
2、不一定准确,欢迎交流(别人都翻过几百遍了吧,再说也没人看)
3、水平有限、随时太监
· 从Vue 2到Vue 3的迁移指南之破坏性特性(一、全局API)
· 从Vue 2到Vue 3的迁移指南之破坏性特性(二、全局API的tree-shaking)
· 从Vue 2到Vue 3的迁移指南之破坏性特性(三、v-model)
· 从Vue 2到Vue 3的迁移指南之破坏性特性(四、渲染函数API)
函数式组件
概览
这些变化可以概括为:
-
函数式组件在 2.x 中所提升的性能在 3.x 中已经是微不足道的了,所以我们推荐仅适用有状态组件
-
函数式组件现在只能通过使用一个接受了
props与context(包含了slots、attrs、emit) 的简单函数去创建 -
破坏性的: 单文件组件中
<template>的functional属性已移除 -
破坏性的: 创建组件的函数中,
{ functional: true }选项已移除
获取更多信息,请继续阅读!
介绍
在 Vue 2 中,函数式组件主要有两种使用场景:
- 作为一种性能优化方式,因为它初始化会比有状态的组件更快
- 返回多个根节点
然而,在 Vue 3 中,有状态组件的性能已经优化到跟前者几乎没区别,除此之外,有状态组件现在也具有返回多个根节点的功能。
结果上看,函数式仅存的作用就是创建一个简单组件,比如创建一个具有动态标题(heading)的组件,除此之外,我们都推荐您像通常情况那样使用有状态组件。
2.x 语法
在 2.x 中,如果我们要使用一个可以动态生成合适标题(heading)(包含了 h1、 h2、h3 等)的 <dynamic-heading> 组件时,用单文件组件我们可以这么写:
// Vue 2 函数式组件例子
export default {
functional: true,
props: ['level'],
render(h, { props, data, children }) {
return h(`h${props.level}`, data, children)
}
}
又或者有人更喜欢在单文件组件里面用 <template>:
// Vue 2 使用<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 属性的对象。
除此之外,现在 h 需要全局导入,而不是隐式地在 render 函数中提供。
拿前面的 <dynamic-heading> 组件来说,现在是这样的:
import { h } from 'vue'
const DynamicHeading = (props, context) => {
return h(`h${props.level}`, context.attrs, context.slots)
}
DynamicHeading.props = ['level']
export default DynamicHeading
单文件组件 (SFCs)
3.x 中,有状态组件与函数式组件之间的性能差异已经大幅度减少了,在绝大部分场景中都可以忽略不计。从结果上看,在单文件组件上使用 functional 的开发者只需要把标记去掉即可完成迁移,无需进行其他工作。
拿前面的 <dynamic-heading> 组件来说,现在是这样的:
<template>
<component
v-bind:is="`h${props.level}`"
v-bind="$attrs"
/>
</template>
<script>
export default {
props: ['level']
}
</script>
主要不同点:
<template>上的functional属性已移除listeners现已作为$attrs的一部分,并且可以移除
后续
获取更多关于函数式组件的用法以及渲染函数的变化,请参阅: