【译】Vue.js函数式组件,什么是函数式组件?为何要用?何时用?

原文:medium.com/js-dojo/vue…
做者:Austin Gil
翻译:前端小白前端

TL,DR: 若是你的组件不须要状态,那么将其转换为函数式组件能够将性能提升70%。vue

什么是函数式组件

函数组件(不要与 Vue 的 render 函数混淆)是一个不包含状态和实例的组件。git

简单的说,就是组件不支持响应式,而且不能经过 this 关键字引用本身。github

使用 Vue Template 的函数式组件
使用 render 函数的函数式组件

访问组件属性

  • slots: 一个返回 slots 对象的函数

没有状态或实例,你可能会好奇如何引用数据或方法,Vue为底层的 render 函数提供一个 context 参数对象。数组

这个 context 参数对象具备下列属性:框架

  • props: 全部的 props 对象
  • children: VNode 子节点数组
  • scopedSlots: (vue2.6.0+) 暴露传入做用域插槽的对象。将普通插槽做为函数暴露出去
  • data: 所有的数据对象,做为 createElement 函数的第二个参数传递给组件
  • parent: 对父组件的引用
  • listeners: (vue2.3.0+) 包含父级注册的事件侦听器的对象。也是 data.on 的别名
  • injections: (v2.3.0+) 若是使用了 inject 选项,则该对象包含了应当被注入的属性

访问这个 context 参数很是简单,例如,咱们想使用 props,能够这样作:函数

在 Template 中访问组件的 context
在 render 函数中访问组件的 context

关于函数式组件和 props 的简要说明

在函数式组件中,实际上不须要注册它接受的 props,可是,若是你注册了它们,仍然会根据它们的配置对它们进行验证。我我的认为注册它们仍然是一个好主意,这样我就能够指定类型、是否必需、默认值或自定义验证器。性能

为何函数式组件很棒

函数式组件可能会给咱们使用组件带来更多的复杂性,但为何仍是须要呢?学习

速度

由于函数式组件没有状态,因此它们不须要像Vue的响应式系统同样须要通过额外的初始化。测试

函数式组件仍然会对相应的变化作出响应式改变,好比新传入新的 props,可是在组件自己中,它没法知道数据什么时候发生了更改,由于它不维护本身的状态。

对于那些喜欢看数字说话的人,我作了一个基准测试,渲染1000个列表,有状态组件和函数式组件,有状态组件耗时140ms,函数式组件耗时40ms。

参考示例:codesandbox.io/s/vue-templ…

对于大型应用程序,在使用函数式组件以后,你会看到DOM的渲染、更新会有重大改进。

何时使用函数式组件

函数式组件可能不适用于许多状况。毕竟,使用 JavaScript 框架的目的是构建响应式的应用程序。在 Vue 中,若是没有响应式,就没法作到这一点。

然而,有些场景就很适合函数式组件的使用:

  • 一个简单的展现组件,也就是所谓的 dumb 组件。例如, buttons, pills, tags, cards,甚至整个页面都是静态文本,好比 About 页面。
  • “高阶组件”——用于接收一个组件做为参数,返回一个被包装过的组件
  • v-for 循环中的每项一般都是很好的候选项

注意

当我在下面这种状况下使用时,就遇到了一个小问题:

使用 <template> 标签,经过 prop 接收数据,有时候咱们想在 template 里面修改数据

对于标准的 Vue 组件,使用方法或计算属性都很容易。对于函数式组件,咱们没法访问方法或计算属性。

可是,有一种方法能够作到这点:

假设咱们的组件接受一个 user prop,它是一个对象,具备firstNamelastName 属性,咱们想要渲染一个显示全名的模板

在函数式组件的 <template> 中,咱们在组件定义是提供一个方法,而后使用Vue提供的 $options 属性,能够访问这个特殊的方法。

函数式组件中的计算属性

我我的没有遇到过这个问题,是一个社区成员发现的,当嵌套具备做用域插槽的函数式组件,其行为与嵌套具备做用域插槽的有状态组件是不一样的,参考连接

结论

若是你关心性能方面,或者正在处理一个大型应用,能够考虑下函数式组件的应用。它的学习曲线很低,并且会为性能带来很大提高。

相关文章
相关标签/搜索