在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
為字串型別,可以作為第二個引數definition
的name
屬性。重點看看下面這句**
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...