1. 程式人生 > 其它 >Vue原始碼解析——元件化機制

Vue原始碼解析——元件化機制

技術標籤:原始碼分享Vuevue

元件化機制

元件宣告Vue.component()

initAssetRegisters(Vue) src/core/global-api/assets.js 元件註冊使用extend方法將配置轉換為建構函式並新增到components選項

元件例項建立及掛載:觀察生成的渲染函式

"with(this){return _c('div',{attrs:{"id":"demo"}},[ _c('h1',[_v("虛擬DOM")]),_v(" "), _c('p',[_v(_s(foo))]),_v("
"), _c('comp') // 對於元件的處理並無特殊之處 ],1)}"

整體流程

首先建立的是根元件,首次_render()時,會得到整棵樹的VNode結構

流程如下:

new Vue() => $mount() => vm._render() => createElement() => createComponent() => patch => createElm => createComponent()

建立自定義元件:VNode

src\core\vdom\create-element.js

_createElement實際執行VNode建立的函式,由於傳入tag是非保留標籤,因此判定為自定義元件通過 createComponent去建立

createComponent src/core/vdom/create-component.js 建立元件VNode,儲存了上一步處理得到的元件建構函式,props,事件等

注意元件鉤子安裝和元件tag指定規則

建立自定義元件例項

根元件執行更新函式時,會遞迴建立子元素和子元件,入口createElm

createEle() core/vdom/patch.js line751

首次執行_update()時,patch()會通過createEle()建立根元素,子元素建立研究從這裡開始

createComponent core/vdom/patch.js line144

自定義元件建立

// 元件例項建立、掛載
if (isDef(i = i.hook) && isDef(i = i.init)) { i(vnode, false /* hydrating */) } if (isDef(vnode.componentInstance)) { // 元素引用指定vnode.elm,元素屬性建立等 initComponent(vnode, insertedVnodeQueue) // 插入到父元素 insert(parentElm, vnode.elm, refElm) if (isTrue(isReactivated)) { reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm) } return true }

結論:

  • 元件建立順序自上而下
  • 元件掛載順序自下而上