本节将看下初始化中的$options:
1 Vue.prototype._init = function (options?: Object) { 2 const vm: Component = this 3 // a uid 4 vm._uid = uid++ 5 6 // a flag to avoid this being observed 7 vm._isVue = true 8 // merge options 9 if (options && options._isComponent) { 10 // optimize internal component instantiation 11 // since dynamic options merging is pretty slow, and none of the 12 // internal component options needs special treatment. 13 initInternalComponent(vm, options) 14 } else { 15 vm.$options = mergeOptions( 16 // merge Vue.option 17 resolveConstructorOptions(vm.constructor), 18 // new Vue(data) data for object 19 options || {}, 20 // current instance 21 vm 22 ) 23 } 24 ……………………………… 25 }
通过上边的代码可以看到 ,初始化时vm.$options被mergeOptions方法赋值。那么mergeOptions又做了哪些事情呢?
一. 检查组件名称是否符合要求( 1.是否由字母和-组成,并且以字母开头;2.检测你所注册的组件是否是内置的标签)
1 if (process.env.NODE_ENV !== ‘production‘) { 2 checkComponents(child) 3 } 4 5 /** 6 * Validate component names 7 */ 8 function checkComponents (options: Object) { 9 for (const key in options.components) { 10 validateComponentName(key) 11 } 12 } 13 14 export function validateComponentName (name: string) { 15 if (!/^[a-zA-Z][\w-]*$/.test(name)) { 16 warn( 17 ‘Invalid component name: "‘ + name + ‘". Component names ‘ + 18 ‘can only contain alphanumeric characters and the hyphen, ‘ + 19 ‘and must start with a letter.‘ 20 ) 21 } 22 if (isBuiltInTag(name) || config.isReservedTag(name)) { 23 warn( 24 ‘Do not use built-in or reserved HTML elements as component ‘ + 25 ‘id: ‘ + name 26 ) 27 } 28 }
export const isBuiltInTag = makeMap(‘slot,component‘, true)
二. 规范化 (props, inject,directives)
1 normalizeProps(child, vm) 2 normalizeInject(child, vm) 3 normalizeDirectives(child)
1 /** 2 * Ensure all props option syntax are normalized into the 3 * Object-based format. 4 */ 5 function normalizeProps (options: Object, vm: ?Component) { 6 const props = options.props 7 if (!props) return 8 const res = {} 9 let i, val, name 10 if (Array.isArray(props)) { 11 i = props.length 12 while (i--) { 13 val = props[i] 14 if (typeof val === ‘string‘) { 15 name = camelize(val) 16 res[name] = { type: null } 17 } else if (process.env.NODE_ENV !== ‘production‘) { 18 warn(‘props must be strings when using array syntax.‘) 19 } 20 } 21 } else if (isPlainObject(props)) { 22 for (const key in props) { 23 val = props[key] 24 name = camelize(key) 25 res[name] = isPlainObject(val) 26 ? val 27 : { type: val } 28 } 29 } else if (process.env.NODE_ENV !== ‘production‘) { 30 warn( 31 `Invalid value for option "props": expected an Array or an Object, ` + 32 `but got ${toRawType(props)}.`, 33 vm 34 ) 35 } 36 options.props = res 37 } 38 39 /** 40 * Normalize all injections into Object-based format 41 */ 42 function normalizeInject (options: Object, vm: ?Component) { 43 const inject = options.inject 44 if (!inject) return 45 const normalized = options.inject = {} 46 if (Array.isArray(inject)) { 47 for (let i = 0; i < inject.length; i++) { 48 normalized[inject[i]] = { from: inject[i] } 49 } 50 } else if (isPlainObject(inject)) { 51 for (const key in inject) { 52 const val = inject[key] 53 normalized[key] = isPlainObject(val) 54 ? extend({ from: key }, val) 55 : { from: val } 56 } 57 } else if (process.env.NODE_ENV !== ‘production‘) { 58 warn( 59 `Invalid value for option "inject": expected an Array or an Object, ` + 60 `but got ${toRawType(inject)}.`, 61 vm 62 ) 63 } 64 } 65 66 /** 67 * Normalize raw function directives into object format. 68 */ 69 function normalizeDirectives (options: Object) { 70 const dirs = options.directives 71 if (dirs) { 72 for (const key in dirs) { 73 const def = dirs[key] 74 if (typeof def === ‘function‘) { 75 dirs[key] = { bind: def, update: def } 76 } 77 } 78 } 79 }
三. Vue 选项的合并
1 const options = {} 2 let key 3 for (key in parent) { 4 mergeField(key) 5 } 6 for (key in child) { 7 if (!hasOwn(parent, key)) { 8 mergeField(key) 9 } 10 } 11 function mergeField (key) { 12 const strat = strats[key] || defaultStrat 13 options[key] = strat(parent[key], child[key], vm, key) 14 }
高清原图地址:https://github.com/huashuaipeng/vue--/blob/master/vm.%24options%20%EF%BC%88Vue%E5%AE%9E%E4%BE%8B%E4%B8%8A%E7%9A%84%24options%EF%BC%89.png
代码参考:
https://github.com/vuejs/vue/blob/dev/src/core/util/options.js
官网:
https://cn.vuejs.org/v2/api/#vm-options
原文地址:https://www.cnblogs.com/hsp-blog/p/9385904.html
时间: 2024-10-08 10:08:51