【譯】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 屬性,能夠訪問這個特殊的方法。

函數式組件中的計算屬性

我我的沒有遇到過這個問題,是一個社區成員發現的,當嵌套具備做用域插槽的函數式組件,其行爲與嵌套具備做用域插槽的有狀態組件是不一樣的,參考連接

結論

若是你關心性能方面,或者正在處理一個大型應用,能夠考慮下函數式組件的應用。它的學習曲線很低,並且會爲性能帶來很大提高。

相關文章
相關標籤/搜索