摘要:本文主要對組件化開發(fā)中子組件的異步加載和其生命周期進(jìn)行一些探討。異步組件討論異步加載,需要先了解下異步組件。生命周期控制在使用子組件或者叫局部注冊時,我們可能需要在子組件實例化或者叫創(chuàng)建完畢后做某些事情。
前端開發(fā)社區(qū)的繁榮,造就了很多優(yōu)秀的基于 MVVM 設(shè)計模式的框架,而組件化開發(fā)思想也越來越深入人心。這其中不得不提到 Vue.js 這個專注于 VM 層的框架。
本文主要對 Vue.js 組件化開發(fā)中子組件的異步加載和其生命周期進(jìn)行一些探討。閱讀本文需要對 Vue.js 有一定的了解。
注意:本文中的一些例子代碼,是以 vue-cli 采用 webpack 模板初始化的項目為基礎(chǔ)。異步組件
討論異步加載,需要先了解下異步組件。Vue.js 的異步組件是把組件定義為一個工廠函數(shù),在組件需要渲染時觸發(fā)工廠函數(shù),并且把結(jié)果緩存起來,用于后面的再次渲染。例如注冊一個全局異步組件:
Vue.component("async-demo", function(resolve, reject) { setTimeout(function() { // 將組件定義傳入 resolve 回調(diào)函數(shù) resolve({ template: "I am async!" ? ? ?// 組件的其他選項 }) }, 1000) })
異步子組件和全局注冊很類似:
Vue.component("parent-demo", { ?// 父組件的其他選項 ?components: { ? ?"async-demo": function(resolve, reject) { setTimeout(function() { // 將組件定義傳入 resolve 回調(diào)函數(shù) resolve({ template: "I am async!" ? ? ? ? ?// 子組件的其他選項 }) }, 1000) } } })
工廠函數(shù)的第一個參數(shù) resolve 為成功后的回調(diào),第二個參數(shù) reject 為失敗后的回調(diào),可以在這里提示用戶加載失敗等。
這里使用 setTimeout 只是為了模擬異步,在實際項目中,應(yīng)該配合 webpack 的代碼分離功能來實現(xiàn)異步加載。
異步加載在實際的項目中,如果不使用異步加載,則 Vue.js 組件的 JS、CSS 和模板都會打包到一個 .js 文件中,這個文件可能達(dá)到幾 MB 甚至更多,嚴(yán)重影響首屏加載時間。所以在項目中我們需要啟用組件的異步加載。
webpack 代碼分離webpack 的代碼分離有兩種,第一種,也是優(yōu)先選擇的方式是,使用符合 ECMAScript 提案的 import() 語法。第二種,則是使用 webpack 特定的 require.ensure。讓我們先看看第一種:
import() 調(diào)用會在內(nèi)部用到 promises。如果在舊有版本瀏覽器中使用 import(),記得使用一個 polyfill 庫(例如 es6-promise 或 promise-polyfill),來 shim Promise。
Vue.component( "async-demo", // 該 import 函數(shù)返回一個 Promise 對象。 () => import("./async-demo") )
上面的例子中,前文提到的工廠函數(shù)支持返回一個 Promise 對象,所以可以使用 import() 這種代碼分離方式。
局部注冊也是類似的:
Vue.component("parent-demo", { ?// 父組件的其他選項 ?components: { ? ?"async-demo": () => import("./async-demo") } })
本質(zhì)上,import() 函數(shù)返回一個 Promise 實例,你可以自定義這個過程,下文會有說明。
第二種 webpack 代碼分離是這樣的:
Vue.component("async-demo", function(resolve) { require.ensure([], function(require) { resolve(require("./async-demo")) }, function(error) { ? ?// 加載出錯執(zhí)行這里 ?}) })
看起來比較繁瑣,如果你使用 webpack 2 及以上版本,則不建議使用第二種方式。
生命周期控制在使用子組件(或者叫局部注冊)時,我們可能需要在子組件實例化(或者叫創(chuàng)建完畢)后做某些事情。在非異步的子組件中,我們很容易做這件事:
上例中使用了 Vue.js 的子組件引用,所以可以在生命周期函數(shù) mounted 中很方便的獲取到子組件的實例,這樣就可以在這個函數(shù)中處理一些子組件實例化后要做的事情。
但是在異步子組件中,mounted 函數(shù)中是無法獲取到子組件的實例的,所以我們需要一些技巧來實現(xiàn)這個功能。
上例中,可以看到我們對組件異步加載做了一些特殊的控制,其中 import().then() 則是在加載完子組件的 .js 文件后,實例化子組件之前的回調(diào),如果需要處理出錯的情況,則 import().then().catch() 即可。
以上代碼只是注入了一個 created 函數(shù),如果要注入其他生命周期函數(shù),例如 mounted,也是類似的:
通過上面的討論,我們可以做到完全控制 Vue.js 組件的異步加載的全過程,這對于需要精確控制子組件加載的組件,會有很大的幫助。
演示項目根據(jù)上面的思路,寫了一個基于 Bootstrap 的異步彈窗演示項目:
https://github.com/hex-ci/vue...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/92126.html
摘要:雖然計算屬性在大多數(shù)情況下更合適,但有時也需要一個自定義的偵聽器,當(dāng)需要在數(shù)據(jù)變化時執(zhí)行異步或開銷較大的操作時,通過偵聽器最有用。路由的鉤子函數(shù)首頁可以控制導(dǎo)航跳轉(zhuǎn),,等,一般用于頁面的修改。 談?wù)勀銓VVM開發(fā)模式的理解 MVVM分為Model、View、ViewModel三者。Model 代表數(shù)據(jù)模型,數(shù)據(jù)和業(yè)務(wù)邏輯都在Model層中定義;View 代表UI視圖,負(fù)責(zé)數(shù)據(jù)的展示;...
摘要:可以在該鉤子中進(jìn)一步地更改狀態(tài),不會觸發(fā)附加的重渲染過程。我工作中只用到,對和不怎么熟與的區(qū)別相同點都支持指令內(nèi)置指令和自定義指令都支持過濾器內(nèi)置過濾器和自定義過濾器都支持雙向數(shù)據(jù)綁定都不支持低端瀏覽器。 看看面試題,只是為了查漏補缺,看看自己那些方面還不懂。切記不要以為背了面試題,就萬事大吉了,最好是理解背后的原理,這樣面試的時候才能侃侃而談。不然,稍微有水平的面試官一看就能看出,是...
摘要:在第一版的基礎(chǔ)上進(jìn)行了優(yōu)化,新增一些面試題知識點,對一些知識點進(jìn)行更加深入的描述??梢栽谠撱^子中進(jìn)一步地更改狀態(tài),不會觸發(fā)附加的重渲染過程。改變中的狀態(tài)的唯一途徑就是顯式地提交。這兩個可以在不進(jìn)行刷新的情況下,操作瀏覽器的歷史紀(jì)錄。 在第一版的基礎(chǔ)上進(jìn)行了優(yōu)化,新增一些面試題/知識點,對一些知識點進(jìn)行更加深入的描述。 一、對于MVVM的理解? MVVM 是 Model-View-Vie...
閱讀 3207·2023-04-25 14:15
閱讀 2888·2021-11-04 16:11
閱讀 3445·2021-10-14 09:42
閱讀 511·2019-08-30 15:52
閱讀 2885·2019-08-30 14:03
閱讀 3625·2019-08-30 13:00
閱讀 2169·2019-08-26 11:40
閱讀 3383·2019-08-26 10:25