輕量級 JavaScript 框架 Vue 2.6 釋出,新語法和效能優化
輕量級 JavaScript 框架 Vue 2.6 釋出了,代號 “Macross”。新版帶來了大量的改進、內部更改和新功能。
slots:新語法、效能優化、向 3.0 看齊
Slot 是 Vue 實現靈活組合元件的一個重要機制。在 3.0 的原型開發過程中,開發團隊發現了一些可以進一步改善現有 slot 機制的方法,其中一些改進可以在不破壞更改的情況下被引入 2.x。另外可能會需要破壞性改動的改進,開發團隊會盡量提供漸進的替代方案,使將來的遷移更容易。
新語法
首先是 scoped slot 的新語法。在提出、討論並試驗了多種不同的設計( 1 , 2 , 3 )後,採用了 這個 RFC 所描述的 v-slot
語法。下面是使用命名 slot 的一個簡短示例:
<my-component> <template v-slot:header> <p>Header</p> </template> <template v-slot:item="{ data }"> <h2>{{ data.title }}</h2> <p>{{ data.text }}</p> </template> <template v-slot:footer> <p>Footer</p> </template> </my-component>
新語法統一了單個指令中普通 slot 和 scoped slot 的使用,並強制使用了更明確和可讀性的命名 slot。它還與現有語法完全相容,這使得開發團隊可以在 2.6 版本中釋出它。
如果您已經熟悉現有的 slot 語法,建議閱讀 RFC 以更好地理解新語法背後的基本原理。如果您還不熟悉 slot,建議閱讀 更新的 slot 文件 相反。
效能優化
將在 3.0 版本中看到有關 slot 的另一個改進,是普通 slot 和 scoped slot 的實現的統一,這是因為 scoped slot 在效能方面的優勢。普通 slot 將在父元件的渲染週期中渲染。當 slot 的依賴項發生變化時,會導致父元件和子元件進行重新渲染。另一方面,scoped slot 被編譯成行內函數,並在子元件的渲染週期中被呼叫。這意味著子元件將會收集 scoped slot 所依賴的所有資料依賴項,從而做出更精確的更新。
在 2.6 版本中,開發團隊引入了一種 優化手段 ,進一步確保父元件的依賴項變化僅影響到父元件,並且如果只使用了 scoped slot,就不會強制子元件做出更新。
此外:
-
所有使用新 v-slot 語法的 slot 都將被編譯為 scoped slot,這意味著所有使用新語法的 slot 都會自動獲得性能提升;
-
現在所有普通的 slot 也通過 this.$scopedSlots 暴露出來,這意味著使用 render 函式而不是模板的使用者現在也可以使用 this.$scopedSlots,而不用擔心傳入的 slot 是什麼型別。
在 3.0 中,將不再區分 scoped 與非 scoped slot——所有 slot 將使用統一的語法,被編譯為相同的格式,並具有相同的效能。
非同步錯誤處理
Vue 的內建錯誤處理機制(元件內 errorCaptured hook 和全域性 errorHandler hook)現在也會捕獲 v-on 處理程式內部的錯誤。另外,如果任意一個生命週期 hook 或事件處理程式執行了非同步操作,現在可以從函式中返回一個 Promise,Promise 鏈中任何一個未被捕獲的錯誤都會被髮送給錯誤處理程式。如果使用了 async/await,則會變得更加容易,因為非同步函式隱式返回 Promise:
export default { async mounted() { // if an async error is thrown here, it now will get // caught by errorCaptured and Vue.config.errorHandler this.posts = await api.getPosts() } }
動態指令引數
指令引數現在可以接受動態的 JavaScript 表示式:
<div v-bind:[attr]="value"></div> <div :[attr]="value"></div> <button v-on:[event]="handler"></button> <button @[event]="handler"></button> <my-component> <template v-slot:[slotName]> Dynamic slot name </template> </my-component>
更多細節可以在 這個 RFC 中找到。
為了方便起見,如果引數值為 null,則繫結和監聽器會被移除。(元件庫的作者要注意:這個功能要求 Vue 執行時為 2.6.0 及以上版本。如果你釋出的是預編譯的元件,並希望保持與 2.6 之前版本的相容性,請避免在原始碼中使用該新功能。)
編譯器警告位置資訊
2.6 版本開始,大多數模板編譯警告訊息現在都帶有原始碼位置資訊。這使得我們就能夠為這些警告訊息生成更好的程式碼幀:
顯式建立獨立的響應式物件
2.6 版本引入了一個新的全域性 API,可以顯式建立獨立的響應式物件:
const reactiveState = Vue.observable({ count: 0 })
生成的物件可以直接用在計算屬性或 render 函式中,並在發生變化時觸發對應的更新。
伺服器端渲染期間的資料預取
新的 serverPrefetch hook 允許任何元件(不僅僅是路由級別的元件)在伺服器端渲染期間預取資料,更加靈活並降低了資料獲取和路由器之間的耦合。一些專案(如 Nuxt 和 vue-apollo)已經計劃通過這個新功能來簡化它們的實現。
新 ES 模組構建,可直接匯入使用
之前 ES 模組構建主要目標是與捆綁包一起使用。這些構建包含了在編譯時需要替換為環境變數的內容。Vue 2.6 現在提供了新的 ES 模組構建,可以直接在瀏覽器中使用:
<script type="module"> import Vue from 'https://unpkg.com/vue/dist/vue.esm.browser.js' new Vue({ // ... }) </script>
重要的內部改動
讓 nextTick 恢復使用 Microtask
在 2.5.0 版本中,開發團隊做出了一個內部調整,如果更新是在 v-on 事件處理程式中觸發的,則會導致 nextTick 使用 Macrotask(而不是 Microtask)來讓更新進入佇列。最初這麼做是為了修復一些瀏覽器的邊界情況,但反過來又導致了很多其他問題。在 2.6 版本中,開發團隊為原始問題找到了一個更簡單的修復方案,這樣我們就可以在任何情況下恢復 nextTick 使用 Microtask。
如果你對這方面的技術細節感興趣,請 在此處檢視 。
this.$scopedSlots 函式統一返回陣列
這個變更隻影響 render 函式使用者。在 render 函式中,scoped slot 通過 this.$scopedSlots 暴露為函式。在之前版本,呼叫 scoped slot 函式會根據父元件傳入內容返回單個 VNode 或 VNode 陣列。這種設計實際上是一種疏忽,因為它返回值的型別不確定,可能會導致意外的邊界情況。
在 2.6 版本,scoped slot 函式確保只返回 VNode 陣列或 undefined。如果您的現有程式碼中如果有些地方返回的是陣列但沒有被檢查出來,可能會出問題,需要進行相應的修正。更多細節請看 這裡 。
下載地址: