Vue 2.6 釋出了

Vue 2.6 釋出了

本文由「前端早讀課」授權分享

英文原文:https://medium。com/the-vue-point/vue-2-6-released-66aa6c8e785e

昨天剛剛慶祝了 Vue 釋出五週年,今天我們趁熱打鐵在年三十發布了 Vue 2。6 “Macross”,祝大家新春快樂!

在過去一年裡面我們花了大量的精力在新版的 CLI 和 3。0 的設計/原型調研上,因此 Vue 2。x 相對地已經很久沒有重大更新了。差不多是時候了!這次的 2。6 包含了一些相當有份量的更新,我們在這裡會討論一些亮點——具體細節還請移步完整的 release note。

Slots:新語法,效能最佳化,準備接軌 3。0

Slot /插槽 是 Vue 元件的一個重要機制,因為它使得完全解耦的元件之間可以靈活地被組合。在 3。0 的原型開發過程中,我們發現了一些可以進一步改善現有的 slot 機制的方法。這裡面有些可能會需要少量破壞性的改動,但也有一些可以以完全向後相容的方式被引入 2。x。對於那些需要破壞性改動的改進,我們也儘量透過在 2。x 中引入完全相容的改動來漸進地跟 3。0 的 API 接軌。

新語法

首先,我們為 slot 引入了一套全新的模版語法。語法改動是我們很少做的事情(這也是 3。0 唯一計劃改的語法),所以我們嘗試了多種不同的設計,並且進行了大量的討論。最終我們敲定了基於新的 v-slot 指令的語法(具體設計細節見 RFC)。這裡是兩個簡略的例子:

預設作用域插槽 (default scoped slot)

{{ msg }}

具名插槽 (named slots)

新語法將普通的插槽 (slot) 和作用域插槽 (scoped slot) 統一在一個指令語法下,並在整體上強調明確性 (explicitness) 和一致性 (consistency)。同時,由於新語法和舊語法完全相容,這使得我們可以在 2。6 中釋出它。

如果你已經熟悉現有的 slot 語法並且英語過關,我們建議你完整地閱讀RFC 來更好地理解新語法為什麼這樣設計。如果你對於 slot 並不熟悉,那麼建議你直接看更新過的文件(或是等勾股更新中文翻譯)。

效能最佳化

在 3。0 中我們希望實現的另一個關於 slot 的改進就是統一 slot 和 scoped slot 的內部實現,從而獲得更好的效能最佳化。普通的 slot 是在父元件的渲染函式中被生成的,因此當一個普通的 slot 所依賴的資料發生變化時,首先觸發的是父元件的更新,然後新的 slot 內容被傳到子元件,觸發子元件更新。相比之下,scoped slot 在編譯時生成的是一個函式,這個函式被傳入子元件之後會在子元件的渲染函式中被呼叫。這意味著 scoped slot 的依賴會被子元件收集,那麼當依賴變動時就只會直接觸發子元件更新了。2。6 中我們又引入了另一個最佳化:如果子元件只使用了 scoped slot,那麼父元件自身依賴變動時,不會再強制子元件更新。這個最佳化使得父子元件之間的依賴即使在存在 slot 的情況下依然完全解耦,從而保證最優的整體更新效率。(對比之下 React 使用 render props 時絕大部分情況下都會觸發父子元件一起更新)

除此之外:

所有使用新的 v-slot 語法的 slot 都會被編譯為 scoped slot。這意味著所有使用新語法的 slot 程式碼都會獲得上述的效能最佳化;

所有的非 scoped slot 現在也被以函式的形式暴露在 this。\$scopedSlots 上。如果你是直接用 render 函式的使用者,你現在可以完全拋棄 this。\$slots 而全部用 this。\$scopedSlots 來處理所有的 slots 了。(3。0 中 this。\$slots 將會直接暴露函式,取代 this。\$scopedSlots)

3。0 中將不再有普通 slot 和 scoped slot 的區分——所有的 slot 都使用統一的語法,使用統一的內部實現,獲得同樣的效能最佳化。

非同步錯誤處理

Vue 的內建錯誤處理機制(元件中的 errorCaptured 鉤子和全域性的 errorHandler 配置項)現在也會處理 v-on 偵聽函式中丟擲的錯誤了。另外,如果你元件的生命週期鉤子或是實踐偵聽函式中有非同步操作,那麼可以透過返回一個 Promise 的方式來讓 Vue 處理可能存在的非同步錯誤。如果你用了 async/await,那麼就更簡單了,因為 async 函式預設返回 Promise:

export default { async mounted() { // 這裡丟擲的非同步錯誤會被 errorCaptured 或是 // Vue。config。errorHandler 鉤子捕獲到 this。posts = await api。getPosts() }}

動態指令引數

指令的引數現在可以接受動態的 JavaScript 表示式:

更多細節參見RFC。該語法一個方便的特性是如果表示式的值是 null 則繫結/偵聽器會被移除。

元件庫的作者需要注意:該語法需要 2。6 以上版本的 runtime 的配合。如果你釋出的是預編譯過的元件,並且想要保持跟 2。6 之前版本的相容,不要使用此功能。

編譯警告位置資訊

2。6 開始,所有的編譯器警告都包含了原始碼位置資訊。這使得我們可以生成更有用的警告資訊:

Vue 2.6 釋出了

顯式建立響應式物件

2。6 引入了一個新的全域性 API,可以用來顯式地建立響應式物件:

const reactiveState = Vue。observable({ count: 0})

生成的物件可以直接用在計算屬性 (computed property) 和 render 函式中,並會在被改動時觸發相應的更新。

SSR 資料預抓取

新的 serverPrefetch 鉤子 使得任意元件都可以在服務端渲染時請求非同步的資料(不再限制於路由元件)。這使得整體的資料預抓取方案可以更為靈活,並且可以和路由解耦。Nuxt 和 vue-apollo 等專案已經計劃使用此特性來簡化其內部實現以及提供新的能力。

可直接在瀏覽器中引入的 ES Modules 構建檔案

Vue 之前版本的 ES Modules 構建檔案是針對打包工具的,因此裡面包含了一些需要在構建時替換掉的環境變數,從而導致無法直接在瀏覽器中使用。2。6 包含了一個可以直接在瀏覽器匯入的版本:

重要的內部改動

nextTick 重新調整為全部使用 Microtask

在 2。5 當中我們引入了一個改動,使得當一個 v-on DOM 事件偵聽器觸發更新時,會使用 Macrotask 而不是 Microtask 來進行非同步緩衝。這原本是為了修正一類瀏覽器的特殊邊際情況導致的 bug 才引入的,但這個改動本身卻導致了更多其它的問題。在 2。6 裡面我們對於原本的邊際情況找到了更簡單的 fix,因此這個 Macrotask 的改動也就沒有必要了。現在 nextTick 將會統一全部使用 Microtask。如果你對具體的細節感興趣,可以看這裡。

this。$scopedSlots 函式統一返回陣列

(此改動隻影響使用 render 函式的使用者)在 render 函式中,傳入的 scoped slot 以函式的形式被暴露在 this。\$scopedSlots 上面。在之前的版本中,這些函式會基於父元件傳入的內容不同而返回單個 VNode 或是一個 VNode 的陣列。這是當初實現時的一個疏漏,導致了 scoped slot 函式的返回值型別是不確定的。2。6 當中,所有的 scoped slot 函式都只會返回 VNode 陣列或是 undefined。如果你的現有程式碼中使用了 this。\$scopedSlots 並且沒有處理可能返回陣列的情況,那麼可能會需要進行相應的修正。更多細節參見這裡。

致謝

感謝所有為這個版本貢獻了 PR 的 contributors,以及參與 RFC 討論的社群成員。