$mount 做了什么
- 前面我們提到過嚷量,我們的 demo 在執(zhí)行完
vm.$mount(vm.$options.el)
就把 hello 渲染到了頁面上,那這個過程發(fā)生了什么呢 - 我們先看下
entry-runtime-with-compiler.js
,其中定義了 $mount 方法
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {
el = el && query(el)
if (el === document.body || el === document.documentElement) {
return this
}
const options = this.$options
if (!options.render) {
let template = options.template
if (template) {
if (typeof template === 'string') {
if (template.charAt(0) === '#') {
template = idToTemplate(template)
if (process.env.NODE_ENV !== 'production' && !template) {
warn(
`Template element not found or is empty: ${options.template}`,
this
)
}
}
} else if (template.nodeType) {
template = template.innerHTML
} else {
return this
}
} else if (el) {
template = getOuterHTML(el)
}
if (template) {
const { render, staticRenderFns } = compileToFunctions(template, {
outputSourceRange: process.env.NODE_ENV !== 'production',
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this)
options.render = render
options.staticRenderFns = staticRenderFns
}
}
return mount.call(this, el, hydrating)
}
- 首先它
query $options.el
,通過 query 函數(shù)我們可以發(fā)現(xiàn)這一步實際上就是獲取真實的DOM元素
export function query (el: string | Element): Element {
if (typeof el === 'string') {
const selected = document.querySelector(el)
if (!selected) {
return document.createElement('div')
}
return selected
} else {
return el
}
}
- 接著會判斷獲取的真實 dom元素是否為 body 或 documentElement
- 接下來會判斷 options.render 是否有存在崇决,我們的 demo 里并沒有寫 render,因此繼續(xù)看里面的邏輯
- 沒有 render 它會判斷 options.template 是否存在,如果不存在
template = getOuterHTML(el)
,即獲取 el 的 outerHTML
function getOuterHTML (el: Element): string {
if (el.outerHTML) {
return el.outerHTML
} else {
const container = document.createElement('div')
container.appendChild(el.cloneNode(true))
return container.innerHTML
}
}
然后通過
compileToFunctions
將 template 轉(zhuǎn)化為 render 函數(shù),options.render = render
再調(diào)用
mount.call(this, el, hydrating)
躯砰,這里的 mount 函數(shù)是什么呢辉阶,在代碼第一行里const mount = Vue.prototype.$mount
,所以此處我們調(diào)用的是之前原型對象上的 $mount 函數(shù),這個函數(shù)的做了什么我們會在下一篇中進(jìn)行分析
調(diào)試 demo
-
執(zhí)行 $mount 出 debugger
-
拿到 template
-
template 轉(zhuǎn)化為 render 函數(shù)