mergeOptions方法阅读
mergeOptions
1 | // 合并构造函数原本的options和构造时传入的options |
checkComponents方法
检查构造时传入的options中,components中引入的组件名是否合法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24function checkComponents (options: Object) {
for (const key in options.components) {
// 遍历传入options中的components,并验证引入的组件的合法性
validateComponentName(key)
}
}
export function validateComponentName (name: string) {
if (!/^[a-zA-Z][\w-]*$/.test(name)) { // 命名是否符合正则中的规则
warn(
'Invalid component name: "' + name + '". Component names ' +
'can only contain alphanumeric characters and the hyphen, ' +
'and must start with a letter.'
)
}
if (isBuiltInTag(name) || config.isReservedTag(name)) {
// isBuiltInTag方法是检验该名是否与svg标签或者html标签相同
// isReservedTag方法,检验是否和保留字相同
warn(
'Do not use built-in or reserved HTML elements as component ' +
'id: ' + name
)
}
}
将props统一处理为对象形式的方法,inject和directive具体思路类似,区别在于各自特有的小部分
1 | function normalizeProps (options: Object, vm: ?Component) { |
几种合并策略
钩子函数的合并策略
1 | function mergeHook ( |
流畅图如下
props,methods,inject,computed 的合并
1 | strats.props = |
流程和钩子函数合并类似,只是处理父子合并的时候不同,此处是使用继承的方式,同名属性使用childVal中的值
components,directives,filters 的合并
1 | function mergeAssets ( |
逻辑同上
data,computed的合并
1 | export function mergeDataOrFn ( |
上面代码的最后,都会调用mergeData,下面是mergeData内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16function mergeData (to: Object, from: ?Object): Object {
if (!from) return to
let key, toVal, fromVal
const keys = Object.keys(from)
for (let i = 0; i < keys.length; i++) {
key = keys[i]
toVal = to[key]
fromVal = from[key]
if (!hasOwn(to, key)) {
set(to, key, fromVal)
} else if (isPlainObject(toVal) && isPlainObject(fromVal)) {
mergeData(toVal, fromVal)
}
}
return to
}
to为childVal,from为parentVal
大体思路:
- 没有parent,直接返回child
- 有parent,遍历parent,如果child没有就直接set,
- 如果有child,如果都是对象,递归调用mergeData,不是对象以child为准