在這篇文章中,我將跟大家分享4個有突破性新特性。
- 服務端渲染異步組件
- 包裹組件內實現屬性繼承
- 異步組件支持webpack3
- 組件渲染后可保留HTML注釋
1、服務端渲染異步組件
在vue2.4.0以前版本,由於無法支持服務端渲染異步組件,導致他們通常在SSR中被忽略,只能等待在客戶端渲染。新版本使異步組件有着突破性的進展,同時修復這問題可以讓Vue更好的實現PWAs。
異步組件
異步組件是非常方便的,簡而言之,它能讓你的應用代碼分離,使非必要組件(比如模態,選項卡,折疊內容,其他頁面等)在首頁加載后延遲加載, 從而讓用戶更快的看到主頁。
假如你決定以異步方式加載內容,主組件可能如下所示:
1 <template> 2 <div id="app"> 3 <!--Above-the-fold--> 4 <sync-component></sync-component> 5 6 <!--Below-the-fold--> 7 <async-component></async-component> 8 </div> 9 </template> 10 <script> 11 12 import SyncComponent from './SyncComponent.vue'; 13 const AsyncComponent = import('./AsyncComponent.vue'); 14 15 export default { 16 components: { 17 SyncComponent, 18 AsyncComponent 19 } 20 } 21 </script>
通過使用webpack的動態import
函數,可使異步組件將在服務端頁面后,通過ajax請求被加載。不足就是,當加載中用戶可能只能看到微調框或者是空白區域。
這可以通過服務端渲染
來改進,被標記的異步組件可以在初始頁面內渲染,避免出現微調框或者空白區域,提高用戶體驗。
VUE2.4.0增加server-rendered
屬性使其變得可能。SSR中主組件輸出如下。
<div id="app" server-rendered="true"> <!--Above-the-fold--> <div> Whatever sync-component renders as... </div> <!--Below-the-fold--> </div>
從VUE2.4.0開始,異步組件將被包含在SSR輸出內容中,因此你有無白屏用戶體驗的進行VUE程序代碼分離。
2、組件內新增實現屬性繼承
VUE中一個比較令人煩惱的事情是屬性只能從父組件傳遞給子組件。這也就意味着當你想向嵌套層級比較深組件數據傳遞,只能由父組件傳遞給子組件,子組件再傳遞給孫子組件...像下面這樣
<parent-component :passdown="passdown"> <child-component :passdown="passdown"> <grand-child-component :passdown="passdown"> Finally, here's where we use {{ passdown }}!
demo中只有一兩個屬性還好,試想一下,當在一個真實的項目中,你可能有非常非常多的屬性需要傳遞時,那是怎樣一種恐怖的場景。
事件總線模式或者vuex也可以解決跨非直接父子組件通信的問題,但VUE2.4.0版本提供了一種新的解決方案。事實上,這個新功能是有兩個獨立卻相關的部分組成,首先,組件支持inheritAttrs
的選項,其次需用到實例屬性$attrs
。我們通過一個例子來看它是如何工作的。
例子
我們首先綁定兩個屬性在組件上,propa是組件自己需要使用的,而propb只是組件需要向下傳遞的一個屬性
<my-component :propa="propa" :propb="propb"></my-component>
在Vue2.4.0之前版本,組件內未被注冊的屬性將作為普通html元素屬性被渲染。所以你組件可能定義起來像是這樣
<template> <div>{{ propa }}</div> </template> <script> export default { props: [ 'propa' ] } </script>
它將渲染成下面的樣子
<div propb="propb">propa</div>
propb僅僅被渲染普通html屬性,如果想讓屬性能夠向下傳遞,即使prop組件沒有被使用,你也需要在組件上注冊。
export default {
props: [
'propa',
'propb' // 注冊后才能向下傳遞
]
}
這樣做會使組件預期功能變得模糊不清,同時也難以維護組件的DRY。在Vue2.4.0,可以在組件定義中添加inheritAttrs:false
,組件將不會把未被注冊的propb呈現為普通的HTML屬性。渲染效果如下:
<div>propa</div>
向下傳遞propb
雖然prop在組件中沒有出現,但通過組件實例的$attrs
(也是Vue2.4.0新增功能)獲取。組件的$attrs
包含所有未被注冊的props
<template> <div> {{ propa }} <grand-child v-bind:propb="$attrs.propb"></grand-child> </div> </template> <script> export default { props: [ 'propa' ], inheritAttrs: false } </script>
想象當你需要向多個嵌套層級中,傳遞上千百個屬性時,這個特性使你的在每個中間組件屬性定義變得相當簡潔。
<input v-bind="$attrs">
當然,也可以通過這種方式用v-on綁定事件監聽傳遞函數
<div> <input v-bind="$attrs" v-on="$listeners"> </div>
3、異步組件支持webpack3
作用域提升是最近發布的webpack3的關鍵功能之一。webpack 1和2是將模塊打包到一個獨立的函數作用域內。通過新的ES2015模塊語法實現的范圍提升方法在瀏覽器中的執行速度,比老的獨立范圍的方式要快的多。
兩個星期以前,vue-loader
v13.0.0發布了,並將.vue文件作為ES模塊輸出,這使得vue能夠享受新的變量提升帶來的便利。
由於ES模塊導出方式不同,在Vue項目中用於代碼拆分的簡潔的異步組件語法
例如
const Foo = () => import('./Foo.vue');
// 將改為:
const Foo = () => import('./Foo.vue').then(m => m.default);
然而在Vue2.4.0在處理異步組件時,將自動解析為ES模塊默認導出,允許以前更簡潔的語法。
4、保留HTML注釋
好吧,這個功能看起來並不是那么的重要,然我仍然覺得很酷。在Vue2.4.0之前版本,注釋將被省略
<template> <div>Hello <!--I'm a comment.--></div> </template>
渲染后:
<div>Hello</div>
問題是,有些注釋需要被渲染在頁面中,有些庫可能需要這些注釋。
在Vue2.4.0,你可以使用comments
選項開啟注釋
<template> <div>Hello <!--I'm a comment.--></div> </template> <script> export default { comments: true } </script>