Vue原始碼學習(十一)全域性元件和區域性元件的註冊

2021-10-03 05:14:44 字數 4223 閱讀 4283

vue中元件註冊分為全域性註冊和區域性註冊

全域性註冊

vue.

component

('my-component-name'

,)

區域性註冊
var componenta =

var componentb =

var componentc =

newvue(}

)

無論時全域性元件還是區域性元件一定要註冊後才能使用。

src/core/global-api/assets.js中,initassetregisters方法遍歷asset_types,並定義相關方法

export

function

initassetregisters

(vue: globalapi)

else

if(type ===

'component'

&&isplainobject

(definition))if

(type ===

'directive'

&&typeof definition ===

'function')}

this

.options[type +

's']

[id]

= definition

return definition

}}})}

// src/shared/constants.js

export

const

asset_types=[

'component'

,'directive'

,'filter'

]

也就是說通過initassetregisters方法,給vue建構函式新增了component,directive,filter方法,而initassetregisters會在src/core/global-api/index.js中的initglobalapi中進行呼叫。通過

this

.options[type +

's']

[id]

= definition

把定義的全域性元件新增到vue.options.components物件上。

可以看到vue.component接受兩個引數,id為字串型別,可以作為第二個引數definitionname屬性。重點看看下面這句**

definition =

this

.options._base.

extend

(definition)

上面這行**等價於

definition = vue.

extend

(definition)

從前面的文章分析中我們知道,vue.extend最終會返回元件構造器函式,並且在extend方法中呼叫mergeoptions方法對配置進行合併。

sub.options =

mergeoptions

( super.options,

extendoptions

)

在元件例項化的時候,在initinternalcomponent方法中進行配置合併

const opts = vm.$options = object.

create

(vm.constructor.options)

也就是說此時vm.$options.components的物件中包含了我們定義的全域性元件。

比如vm.$options.components['my-component-name'] = definition

在建立元件vnode的過程中,_createelement方法中會執行以下邏輯

ctor =

resolveasset

(context.$options,

'components'

, tag)

我們看看resolveasset方法

// src/core/util/options.js

/** * resolve an asset.

* this function is used because child instances need access

* to assets defined in its ancestor chain.

*/export

function

resolveasset

( options: object,

type: string,

id: string,

war****sing?

: boolean

): any

const assets = options[type]

// check local registration variations firstif(

hasown

(assets, id)

)return assets[id]

const camelizedid =

camelize

(id)if(

hasown

(assets, camelizedid)

)return assets[camelizedid]

const pascalcaseid =

capitalize

(camelizedid)if(

hasown

(assets, pascalcaseid)

)return assets[pascalcaseid]

// fallback to prototype chain

const res = assets[id]

|| assets[camelizedid]

|| assets[pascalcaseid]

if(process.env.

node_env

!=='production'

&& war****sing &&

!res)

return res

}

如果resolveasset方法有返回值,在_createelement方法中接著呼叫createcomponent方法生成為元件vnode

通過上面的分析,我們應該可以了解到vue.component註冊全域性元件背後的機制,這裡進行了多次merge options,首先將vue.options合併到子類的super.options物件上,在元件例項化的時候,還會進行配置項的合併,最終在元件例項的vm.$options屬性上存在著components物件,而components中有我們定義的全域性元件

components:

通過前面的文章分析我們可以清楚的了解到區域性註冊這種方式在元件例項的vm.$options.components物件上有我們定義的區域性元件

全域性註冊和區域性註冊其實實現思路一致,都是通過配置合併保證在元件例項的$options物件上有我們定義的全域性或區域性元件,以確保能通過resolveasset方法,最終呼叫createcomponent方法生成元件vnode

vue原始碼學習

new vue發生了什麼 此處只針對最簡單基礎的new vue過程,一般專案中採用.vue單檔案元件的形式開發,下面會介紹 對於 runtime compile 版本 初始化乙個 vue 例項的一系列相關環境 watcher,lifecycle,methods等等 compile 將 templat...

vue 元件是否渲染完畢 Vue 原始碼之元件渲染

上篇講了 new vue 發生了哪些事情的大致流程,即如圖所示,今天來分析下元件是如何渲染的基本流程。import vue from vue 這裡的 h 是 createelement 方法 new vue 發生了什麼?首先會執行 vm 例項初始化過程,然後進入到 mount,因為手寫了 rende...

Vue註冊區域性元件和全域性元件

1.新建components目錄,方便管理和修改 2.component資料夾下新建vueaudio元件,注意要用駝峰命名法或者短橫線命名法 export default 3.引用元件 import vueaudio from components vueaudio export default 1...