vlambda博客
学习文章列表

Vue 3 | 函数式组件变形记

开门见山 

从上帝视角看一下发生了什么:

  • 官方团队宣称,Vue 3 中函数式组件的性能提升微乎其微(与 Vue 2.x 相比),所以建议直接使用常规组件就好。
  • 如果想创建一个函数式组件,写一个接收 propscontext 的普通函数就可以了。
  • 废弃:单文件组件(SFC)中 <template>functional 属性被干掉了。
  • 废弃:通过给 Render 函数传递 { functional: true } 以创建函数式组件的方式也被废弃了。

Vue 3 | 函数式组件变形记

事情是这样的... Vue 3 | 函数式组件变形记

在 Vue 2.x 的版本中,函数式组件主要有以下两个使用场景:

  • 因为函数式组件的初始化和渲染都很快(快过常规组件),所以通常作为一种提升性能的角色出现
  • 用来返回多个根节点

然而,在 Vue 3 中,常规组件的性能有了很大提升,相比之下,这时的函数式组件在性能上失去了以往的优势。另外,现在的常规组件也支持返回多个根节点了。因此,函数式组件仅剩的唯一用途就是用来实现简单组件了,比如一个动态生成不同标题的组件(市场被挤压,好可怜)。

Vue 3 | 函数式组件变形记

2.x 版本是这样的 Vue 3 | 函数式组件变形记

就用上面提到的例子,那个动态生成不同标题的组件:

// Vue 2 函数式组件
export default {
  functionaltrue,
  props: [level],
  render(h, { props, data, children }) {
    return h(`h${props.level}`, data, children);
  }
}

也可以采用 <template> 函数式组件的方式去写:

// Vue 2 用模版实现的函数式组件
<template>
 <component :is="`h${props.level}`"/>
</template>

<script>
export default {
  props: ['level'],
}
</script>

3.x 安利时刻 Vue 3 | 函数式组件变形记

在 Vue 3 中,只要是通过普通函数创建的组件,都是函数式组件,也不用传递之前那个 { functional: true }的参数了。

函数会接受两个参数:propscontext 。前者不用说了,后者包含了组件的 attrsslotsemit 等属性。

此外,之前也有提到,h 也不再作为函数的参数了,需要手动从全局引入。

各位观众!现在把上面那个例子改写成 Vue 3 的写法:

import { h } from 'vue';

const DynamicHeading = (props, context) => {
  return h(`h${props.level}`, context.attrs, context.slots);
}

DynamicHeading.props = ['level'];

export default DynamicHeading;

还有一件非常幸福的事情:如果我们需要从 Vue 2 的 <template> 函数式组件迁移到 Vue 3,直接把组件的 functional 属性去掉就好了,不需要其他额外的操作。


如果你想获得关于 Vue 3 函数式组件的更多信息,请访问:https://v3.vuejs.org/guide/migration/functional-components.html#components-created-by-functions(目前还没有中文本)。