接上篇
$mount方法总结
- 获得模版
template
。 - 调用 compileToFunctions 获得 template 对应的
render函数
。 - 调用 mountComponent ,其中的
vm._render()
将render函数
转化为vNode
。 vm._update()
以生成的vNode
为参数发布更新。
vm._render()
1 | core\instance\render.js |
vm._render主要是这一句:vnode = render.call(vm._renderProxy, vm.$createElement)
,第一个参数可以直接看做this,第二个参数是 createElement 方法。
vm.$options.render 的内容
以这段代码为例:1
2
3
4
5
6
7
8
9
10
11
12var vm = new Vue({
el: '.logo',
data: { a: 1 },
template: `
<div>
hello{{ a }}
<div>111</div>
<div>222</div>
</div>
`
})
console.log(vm.$options.render)
这里输出的是一段匿名函数1
2
3
4(function anonymous(
) {
with(this){return _c('div',[_v("hello"+_s(a)),_c('div',[_v("111")]),_c('div',[_v("222")])])}
})
这些函数简写对应如下:
_c = createElement // createElement 其实就是 _createElement
_v = createTextVNode
_s = toString
// 等…..其他的可以在 core\instance\render-helpers\index.js 找。
_createElement方法
1 | // core\vdom\create-element.js |
- 如果tag是浏览器中存在的标签,则返回
new Vnode()
- 如果是个组件,则返回
createComponent()
- 如果是未知元素也返回
new VNode()
resolveAsset:寻找options中对应组件,作为 createComponent
的第一个参数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38core\util\options.js
export function resolveAsset (
options: Object,
type: string,
id: string,
warnMissing?: boolean
): any {
/* istanbul ignore if */
if (typeof id !== 'string') {
return
}
const assets = options[type] // 找出options中的所有组件 --> vm.$options['components']
// 先检查本地的 components 有没有对应的组件(对应形参id)
if (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' && warnMissing && !res) {
warn(
'Failed to resolve ' + type.slice(0, -1) + ': ' + id,
options
)
}
return res
}
最终生成了vNode:
vm._update()
1 | // core\instance\lifecycle.js |
这里的 vm.__patch__
就是 core\vdom\patch.js
中的 patch
方法。