前言
在vue官方資料中,我們可以可以很學會如何通過vue構建“動態組件”以及“異步組件”,然而,在官方資料中,并沒有涉及到真正的“動態異步”組件,經過大量的時間研究和技術分析,我們給出目前比較合理的技術實現方式,并分析一下vue動態異步組件的原理
動態組件 & 異步組件的存在,使得我們更方便地控制首屏代碼的體積,加快加載速度。
拋開具體細節不談,一個普通 Vue 組件從創建到展現在頁面里,主要經歷了以下流程:
// 組件 Object{ template: '<div>I am async!</div>'}// 經過 compileToFunctions 得到對應的 render function with(this) { return _c('div', [_v("I am async!")])}// 在經過 render 得到 Vnode 再 update 成為真實DOM動態組件&異步組件與之有什么區別呢?
主要區別在于 render 中 createComponent 這一步,舉例。
// 組件Vue.component('example', { template: '<div>I am async!</div>'})普通組件在 createComponent 時,會依據開發者自定義的 options,利用 Vue.extend 生成對應的構造函數,從而得到對應的 Vnode 。而一個異步組件
// 異步組件Vue.component('async-example', function (resolve, reject) { // 利用 setTimeout 模擬請求 setTimeout(function () { // 向 `resolve` 回調傳遞組件定義 resolve({ template: '<div>I am async!</div>' }) }, 1000)})則是要經過一系列處理,具體過程如下
在源碼的 create-component。
// async componentlet asyncFactoryif (isUndef(Ctor.cid)) { asyncFactory = Ctor Ctor = resolveAsyncComponent(asyncFactory, baseCtor, context) if (Ctor === undefined) { // return a placeholder node for async component, which is rendered // as a comment node but preserves all the raw information for the node. // the information will be used for async server-rendering and hydration. return createAsyncPlaceholder( asyncFactory, data, context, children, tag ) }}首先 Ctor 就與之前不同,這里為一個 function
function (resolve, reject) { // 利用 setTimeout 模擬請求 setTimeout(function () { // 向 `resolve` 回調傳遞組件定義 resolve({ template: '<div>I am async!</div>' }) }, 1000)}之后調用 resolveAsyncComponent(asyncFactory, baseCtor, context)
resolveAsyncComponent 在源碼的 resolveAsyncComponent。
resolveAsyncComponent 的主要功能是定義 Ctor 所需要的 resolve 、reject 函數
// factory 為 Ctorfactory(resolve, reject)
以 resolve 函數為例
const resolve = once((res: Object | Class<Component>) => { // 緩存 resolved factory.resolved = ensureCtor(res, baseCtor) // 強制渲染 if (!sync) { forceRender(true) }})
新聞熱點
疑難解答
圖片精選