vue版本:v2.7.10
src/platforms/web/runtime/index.ts
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
挂载元素的实现在mountComponent函数中
src/core/instance/lifecycle.ts
export function mountComponent(
vm: Component,
el: Element | null | undefined,
hydrating?: boolean
): Component {
vm.$el = el
if (!vm.$options.render) {
// 还不知道有啥用
vm.$options.render = createEmptyVNode
....
}
// beforeMount钩子
callHook(vm, 'beforeMount')
let updateComponent
if (__DEV__ && config.performance && mark) {
updateComponent = () => {
// 开发环境相比生产环境多了性能检测
const name = vm._name
const id = vm._uid
const startTag = `vue-perf-start:${id}`
const endTag = `vue-perf-end:${id}`
mark(startTag)
const vnode = vm._render()
mark(endTag)
measure(`vue ${name} render`, startTag, endTag)
mark(startTag)
vm._update(vnode, hydrating)
mark(endTag)
measure(`vue ${name} patch`, startTag, endTag)
}
} else {
updateComponent = () => {
vm._update(vm._render(), hydrating)
}
}
const watcherOptions: WatcherOptions = {
before() {
if (vm._isMounted && !vm._isDestroyed) {
// 如果已经挂载过了,需要调用beforeUpdate钩子
callHook(vm, 'beforeUpdate')
}
}
}
// 创建渲染Watcher,传入updateComponent作为更新函数,即
// Watcher -> vm._render -> vm.update
new Watcher(
vm,
updateComponent,
noop,
watcherOptions,
true /* isRenderWatcher */
)
hydrating = false
// _preWatchers是通过setup生成的
const preWatchers = vm._preWatchers
if (preWatchers) {
for (let i = 0; i < preWatchers.length; i++) {
preWatchers[i].run()
}
}
if (vm.$vnode == null) {
// 挂载标识
vm._isMounted = true
// mounted钩子
callHook(vm, 'mounted')
}
return vm
}
Watcher涉及内容较多,下一篇单独讲解。