2020年關於 Vue 3 你須要知道的事

medium.com/swlh/what-y… 原文連接html

如今 VueJS 是最熱的框架之一,它在2019的周下載量翻了一倍。vue

下載量對比

2020年Vue3發佈時,它將更加流行。react

如今Vue團隊的重點在使它可以適合全部開發者,新版本將更強大、更有效率。同時有不少的內部優化將讓咱們用的更爽。git

Vue3也給開發者更多的控制方法(若是你想要),它讓咱們可以使用直接暴露的Vue響應式API準確控制咱們項目,編寫自定義編譯和渲染方法。github

下面是一些重大變化,來自尤雨溪的幾回演講和RFC(request for comments)Github 倉庫api

Vue3 使用基於Proxy的觀察者

響應式是VueJS的核心,它須要數據有依賴,觀察、更新數據來反應任何變化。數組

Vue2使用 Object.defineProperty 去建立getters 和 setters 實現響應式。緩存

使用 Object.defineProperty 這裏有兩個主要的問題,事實上,他們足夠了,甚至在官方文檔中也提到了框架

  1. 響應式屬性不可以動態添加、刪除
  2. 這裏有兩個關於動態數組的問題
    • 經過下標設置元素不是響應式的
    • 修改數組長度是非響應式的
// 經過下標設置數組元素 - 非響應式
vm.items[itemOfItem] = newVal

// 修改數組長度 - 非響應式
vm.items.length = newLength
複製代碼

爲何使用基於Proxy的觀察者

Vue3的解決方案是基於 Proxy 的觀察者,避免了原來的功能限制。異步

老版本和新版本的關鍵區別,Vue2中Object.defineProperty改變原始數據可是Proxy沒有。它使用虛擬化的目標數據,設置不一樣的處理方法來監聽數據的getters和setters。

這個新的方式意味着響應式屬性可以在不使用vm.$set的狀況下添加、刪除屬性。它也消除了Vue2中關於數組的無效極端狀況。

根據尤雨溪在 Medium Post的最好的總結,基於Proxy的觀察者可以支持一下方面:

  • 監測屬性的添加、刪除
  • 監測數組下標和長度的變化
  • 支持 Map、Set、WeakMap、WeakSet

VueMaster有一份關於如何實現基於Proxy的觀察者的很棒的總結。

介紹下 Composition API

在Vue3中這是迄今爲止最著名的變化,它可以幫助咱們組織、重用代碼。

如今若是你在工做中使用Vue,你應該應該用過 Options Api,Options API經過:data、computed、methods等等屬性來組織咱們的代碼。

這是一個很是直觀的系統,吸引了成千上萬的人嘗試VueJS,可是它讓維護一個巨大的組件很是困難。針對一個功能的代碼被分散到幾個地方,每一個地方相隔數百行。

可維護性、可讀性變成了主要的問題

讓咱們看下 Composition API 是如何工做的。

import { reactive, computed } from 'vue'
export default {
  setup(){
    // vue composition api 暴露vue的核心響應式能力
    let state = reactive({
      input: '',
      groceries: [],
      groceriesLeft: computed(() => groceries.length)
    });

    function addGrocery() {
      state.groceries.push(state.input);
      state.input = '';
    }

    function deleteGrocery(index) {
      state.groceries,splice(index, 1);
    }

    return {
      state,
      addGrocery,
      deleteGrocery
    }
  }
}
複製代碼

讓咱們逐步分解發生了什麼

import { reactive, computed } from 'vue'
複製代碼

Vue Composition API暴露了Vue中的不少核心能力,好比響應式、組件方法,因此咱們來引入他們。

export default {
  setup() {
複製代碼

setup方法是Vue3中最大的變化之一,本質上,它可以讓咱們肯定將哪些傳遞給模板,不管返回什麼均可以在模板中訪問。

咱們可以設置響應式數據、生命週期鉤子、計算屬性、定義方法,返回任何咱們想要的東西。

let state = reactive({
  input: '',
  groceries: [],
  groceriesLeft: computed(() => groceries.length)
});
複製代碼

經過將全部數據包裝在響應式方法裏,內部全部的都變成了響應式的。這個狀態模式來自 Composition API 文檔

一個值得注意的是咱們聲明 groceriesLeft 變量的方式,你能看到,它是一個計算屬性,而且定義在setup方法中。再也不有分開聲明的計算屬性了。

function addGrocery() {
  state.groceries.push(state.input);
  state.input = '';
}

function deleteGrocery(index) {
  state.groceries,splice(index, 1);
}
複製代碼

這是典型的函數,惟一獨特的事咱們須要經過狀態對象訪問全部定義在狀態對象中的響應式數據。可是這不是Vue3特有的,它就是普通JavaScript對象。

return {
  state,
  addGrocery,
  deleteGrocery
}
複製代碼

最後,咱們想要在setup方法返回這些函數,這讓屬性和方法可以在模板中被訪問。謝天謝地,模板還和原來同樣,沒啥變化。

第一次據說這些時,有不少反對聲音,由於人們不想被迫從新考慮他們的開發策略。然而咱們據說這將是純淨的添加,人們仍然能夠沒有任何問題的使用Options API。

若是你想上手實踐一下,你能夠在你的項目中使用 Vue Composition API

你能夠在Vue中使用Suspense

Suspense是React的功能,如今Vue3中也能使用。它能讓你在頁面準備好且頁面載入完成後,在你的組件中展現後備內容。

當你在setup方法中異步載入內容是頗有用的。看一下Vue-Next倉庫,看起來setup是一個異步方法而且返回Promise。這個Promise可以被Suspense組件捕獲,渲染後備內容直到它返回。

Suspense可以用來:

  • 建立loading頁面
  • 等待 API 回調
  • 幾乎任何類型的數據請求或者異步的setup方法

這可能實現起來很簡單,你要作的所有就是將你的代碼包裹在Suspense組件中,定義你的主要內容和後備內容。

<Suspense>
  <template >
    <Suspended-component />
  </template>
  <template #fallback>
    Fallback Content
  </template>
</Suspense>
複製代碼

若是你想了解更多關於Suspense的內容,或者你想使用它,查看VueSchool 文章

Vue3中的片斷(Fragments)

片斷(Fragments)是沒有根元素的組件。Vue2中,每個組件必須有且僅能有一個根元素。

這可能讓人頭疼。

在一些用例中,使一個組件返回幾個子元素是很簡單的事情。例如,讓咱們用React舉個例子,表格結構有一個叫Column的自定義組件。

<table>
  <tr>
    <Columns />
  </tr>
</table>
複製代碼

爲了是編譯的HTML有效,Columns組件須要返回元素。可是目前,做爲Vue的組件須要一個單獨的根元素。

Columns組件的模板可能像這樣,這會引發問題。

<div>
  <td>Hello</td>
  <td>World</td>
</div>
複製代碼

這個時候片斷(Fragments)就派上用場了,它容許你返回多個元素從而讓上面的問題可以很簡單的解決。

在Vue3中片斷(Fragments)組件可能像下面這樣。

<Fragment>
  <td>Hello</td>
  <td>World</td>
</Fragment>
複製代碼

而後,由於這將返回兩個元素,因此表格將顯示正常。

<table>
  <tr>
    <td>Hello</td>
    <td>World</td>
  </tr>
</table>
複製代碼

完美!

如今,有一個非官方的Vue 片斷(Fragments)組件庫,它使用內部指令獲取了組件的全部子元素而後移動到合適的位置。

對了,還有 Portals

Portals 是React原生包含的另外一個功能,如今計劃在Vue3中實現。

Portals 容許你跨組件傳遞內容,這意味着你可以在當前組件的做用域以外編輯內容。

當你在向popup、sidebar或者其餘相似組件發送內容時這是很是有幫助的。

和片斷(Fragments)同樣,也有一個非官方的Vue版本 Portal 庫,它在Vue2中帶來了這個功能。根據 vue-next repo,Portals將包含在Vue3中。

這是一個來自 protal-vue 文檔中的舉例的代碼截圖。

code about Portals

<template>
  <div> <div> <p> 下面的內容渲染在PortalVue實現的右側紅色的容器中 </p> <Portal to="right-baisc"> <p class="red"> 這是左側綠色容器的內容。 最酷的是,他可以跨組件,因此你可以向任何地方傳遞內容。 </p> <Portal> </div> </div> </template> 複製代碼

Vue3中Portals的語法和使用方式如今任然不明確,可是應該會和這個類似。

Vue3優化了渲染

Vue3中很大一塊工做就是使它更快、更有效率。實際上,根據尤雨溪在多倫多VueConf上的演講,內部測試代表模板樣式在Vue3中比Vue2速度提高了120%。

有兩個關鍵的優化幫助提高了Vue3的渲染速度:

  1. 塊級樹的優化
  2. 靜態樹的緩存(Hoisting, ^_^ 翻譯成啥呢……)

讓咱們詳細說說上面的兩點。

塊級樹優化

使用虛擬DOM渲染有一個天然的瓶頸,由於每一個組件要跟蹤本身的依賴。

觀察這些依賴很是慢,由於它遞歸的檢查整個元素樹去監測變化。

Vue團隊注意到在組件中的一件事,一個節點結構中大多數是靜態的。若是一個某個部分其實是動態的(由於v-if或者v-for指令),那麼它內部的許多內容時靜態的。

block tree optimizations

由此,Vue3將模板劃分爲靜態和動態部分。如今渲染器知道哪些節點是動態的,它不會浪費時間去檢查靜態節點的變化。

這真的減小了大量須要去被動觀察的元素的數量。

結合全部的節點去建立一個塊級樹,或者一個模板根據指令(v-if/v-for)劃分爲節點塊。

在塊級樹中,每一個節點有如下:

  • 一個靜態節點結構
  • 靜態內容不須要被觀察
  • 動態節點可以被存儲在平級數組中

it's a block tree

這消除了須要去遞歸的檢查每一個元素的需求,大大改善了運行時。

靜態樹緩存(Hoisting)

靜態樹提高並非新提出的(Vue2中已經存在),Vue3有更多顛覆性(aggressive ^_^)技術去提高項目速度。正如名字說表達,靜態書提高不會從新渲染沒有任何依賴的靜態節點。相反,它會重用相同節點。

這極大的減小了虛擬DOM的工做,同時節省了大量項目開銷,主要是垃圾收集方面。

在Vue3中,靜態緩存更有顛覆性,以便儘量高效的工做。

Typescript支持

另外一個變化是,Vue的代碼庫使用Typescript從新寫了一遍。再次重申,一個主要的問題是強制用戶學習Typescript將提升Vue3的上手門檻。

因此Vue團隊讓他對咱們來講很簡單,若是你想要Typescript,使用他。若是你不想要,仍然可使用JavaScript。兩種均可以。

Typscript vs Javascript

若是你像我同樣,你可能會問「爲何用Typescript」。

先不說其餘,Typescript容許你給變量添加類型信息。這可以極大的幫助你維護一個長期運行的項目。

再者,當你工做的IDE支持Typescript,在開發過程當中可以自動補全和展現類型信息。

這都有你決定,事實上使用Typescript寫Vue庫開發者將受益,即便他們繼續使用JavaScript。

自重新的Vue代碼庫使用Typescript,即便你使用JavaScript,自動補全、類型信息和最終文檔都可以從IDE中獲得。這將節省你屢次訪問Vue文檔的時間。

它很是輕量

如今,VueJS已經很是小(gzip後20Kb),可是Vue團隊面臨一個問題,不管用戶是否使用,新功能將增長構建包的大小。

爲了修復這個問題,Vue3將更加模塊化。固然這將增長你在開發時import的次數,這確保了你的項目中沒有不使用的庫。

多虧了Tree shaking(消除非重要代碼),Vue3中減小的代碼大概有gzip後10Kb。固然,許多庫將被從新引入,可是不要緊,咱們並不會被強迫使用全部東西。

vue3 modular

實際上,開發者不用爲他們從不使用的功能付出代價。

一些關於開始學習Vue3的資源

老實說,我認爲Vue核心團隊在聽取社區反饋上和經過官方文章提供不斷的更新一些學習Vue3的最佳地方這點作的很棒。

在寫這篇文章時,我花了大量時間在RFC(Request For comment)和 Vue-next(官方Vue3)倉庫。

其餘資源

你準備好了嗎??

若是你有Vue開發經驗,很明顯,Vue3將要到來的更新將使它更可用、更強大。

從渲染優化到幫助開發者寫更可讀、可維護的代碼,Vue3彷佛要改善Vue2在體驗上的不少痛點。

但願這篇文章很好地解釋Vue3的變化和如何工做。在Vue3官方推出以後,我將必定會更新這篇文章。

感謝閱讀

感謝你閱讀到這裏,翻譯的很差的地方,還請指點。但願個人內容能讓你受用,再次感謝。by llccing 千里

相關文章
相關標籤/搜索