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