通过上节我们对Vue的流程有了一个大概的了解,这节我们将进一步分析
Vue的静态方法
Vue.use
在我们写Vue项目的时候,应该都会用到这个东西,它的作用只有一个就是给我项目注册插件
Vue.use = function (plugin: Function | Object) {
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
const args = toArray(arguments, 1)
args.unshift(this)
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this
}
- 注册插件的时候,我们会存一个数组,用来判断是否已经存储了
- 如果插件有install方法我们把Vue当成第一个参数传给插件,并调用install方法
- 没有install,它本事是一个function,我们直接调用
Vue.mixin
不推荐在应用代码中使用
Vue.mixin = function (mixin: Object) {
this.options = mergeOptions(this.options, mixin)
return this
}
- 全局注册一个混入,影响注册之后所有创建的每个 Vue 实例
Vue.extend
使用基础 Vue 构造器,创建一个“子类”。
Vue.extend = function (extendOptions) {
extendOptions = extendOptions || {}
const Super = this
const SuperId = Super.cid
const cachedCtors = extendOptions._Ctor || (extendOptions._Ctor = {})
if (cachedCtors[SuperId]) {
return cachedCtors[SuperId]
}
const Sub = function VueComponent (options) {
this._init(options)
}
.....
cachedCtors[SuperId] = Sub
return Sub
}
- 判断extendOptions_ _Ctor[SuperId]是否存在,存在直接拿去
- 生成Sub函数,
- 对Sub的options以及方法初始化(具体可以查看源码,比较简单)
- 返回Sub
Vue.component(),Vue.directive(),Vue.filter()
ASSET_TYPES.forEach(type => {
Vue[type] = function (
id, definition
) {
if (!definition) {
return this.options[type + 's'][id]
} else {
if (type === 'component' && isPlainObject(definition)) {
definition.name = definition.name || id
definition = this.options._base.extend(definition)
}
if (type === 'directive' && typeof definition === 'function') {
definition = { bind: definition, update: definition }
}
this.options[type + 's'][id] = definition
return definition
}
}
})
这里可以去看看官网对这几个静态方法的案例讲解,你就会非常清楚了
Vue.prototype._init
mergeOptions
export function mergeOptions (
parent: Object,
child: Object,
vm?: Component
): Object {
...
normalizeProps(child, vm)
normalizeInject(child, vm)
normalizeDirectives(child)
...
const options = {}
let key
for (key in parent) {
mergeField(key)
}
for (key in child) {
if (!hasOwn(parent, key)) {
mergeField(key)
}
}
function mergeField (key) {
const strat = strats[key] || defaultStrat
options[key] = strat(parent[key], child[key], vm, key)
}
return options
}
- normalizeProps格式化props
- normalizeInject格式化inject
- normalizeDirectives格式化directives
- mergeField合并函数,对每一个key采用对应的strats函数进行合并
strats是一个对象
activated: ƒ mergeHook( parentVal, childVal )
beforeCreate: ƒ mergeHook( parentVal, childVal )
beforeDestroy: ƒ mergeHook( parentVal, childVal )
beforeMount: ƒ mergeHook( parentVal, childVal )
beforeUpdate: ƒ mergeHook( parentVal, childVal )
components: ƒ mergeAssets( parentVal, childVal, vm, key )
computed: ƒ ( parentVal, childVal, vm, key )
created: ƒ mergeHook( parentVal, childVal )
data: ƒ ( parentVal, childVal, vm )
deactivated: ƒ mergeHook( parentVal, childVal )
destroyed: ƒ mergeHook( parentVal, childVal )
directives: ƒ mergeAssets( parentVal, childVal, vm, key )
el: ƒ (parent, child, vm, key)
errorCaptured: ƒ mergeHook( parentVal, childVal )
filters: ƒ mergeAssets( parentVal, childVal, vm, key )
inject: ƒ ( parentVal, childVal, vm, key )
methods: ƒ ( parentVal, childVal, vm, key )
mounted: ƒ mergeHook( parentVal, childVal )
props: ƒ ( parentVal, childVal, vm, key )
propsData: ƒ (parent, child, vm, key)
provide: ƒ mergeDataOrFn( parentVal, childVal, vm )
serverPrefetch: ƒ mergeHook( parentVal, childVal )
updated: ƒ mergeHook( parentVal, childVal )
watch: ƒ ( parentVal, childVal, vm, key )
data,provide合并
// 代码截取
if (!childVal) {
return parentVal
}
if (!parentVal) {
return childVal
}
...
//mergeData
if (!hasOwn(to, key)) {
set(to, key, fromVal) // 响应式添加
} else if (
toVal !== fromVal &&
isPlainObject(toVal) &&
isPlainObject(fromVal)
) {
mergeData(toVal, fromVal) // 递归赋值
}
- 如果parentVal不存在,返回childVal
- 如果childVal不存在,返回parantVal
- 如果都存在,遍历parantVal的key
- 如果childVal不存在key,则把parantVal的这个属性响应式赋值给childVal
- 如果childVal存在key,对应的值不相等并且是对象,则递归这个对象进行赋值
- 最后返回childVal
props,methods,inject,computed合并
if (!parentVal) return childVal
const ret = Object.create(null)
extend(ret, parentVal)
if (childVal) extend(ret, childVal)
return ret
- 如果parentVal不存在,则返回childVal
- 如果childVal不存在,则返回parentVal
- 创建一个对象把parentVal,childVal继承返回,后者覆盖前者
'beforeCreate', 'created', 'beforeMount', 'mounted','beforeUpdate', 'updated', 'beforeDestroy', 'destroyed', 'activated', 'deactivated', 'errorCaptured', 'serverPrefetch'合并
const res = childVal
? parentVal
? parentVal.concat(childVal)
: Array.isArray(childVal)
? childVal
: [childVal]
: parentVal
return res
? dedupeHooks(res)
: res
// dedupeHooks
function dedupeHooks (hooks) {
const res = []
for (let i = 0; i < hooks.length; i++) {
if (res.indexOf(hooks[i]) === -1) {
res.push(hooks[i])
}
}
return res
}
- childVal不存在,返回parentVal
- parentVal不存在,返回[childVal]
- 都存在采用合并数组,parentVal.concat(childVal)
- dedupeHooks排重
'component', 'directive', 'filter'合并
const res = Object.create(parentVal || null)
if (childVal) {
return extend(res, childVal)
} else {
return res
}
- childVal不存在,返回parentVal
- parentVal不存在,返回childVal
- 如果都存在,继承parentVal,childVal,后者覆盖前者
小节:
- 了解Vue的静态方法
- mergeOptions对options合并规则
网友评论