options.el
为Vue提供挂载的目标,在源码里可以看到如果一个实例没有提供该属性,则页面什么都不会发生,后续需要自己手动调用 vm.$mount
挂载节点
...
if(vm.$options.el) {
vm.$mount(vm.$options.el)
}
实例方法 vm.$mount
源码是从query
函数获取节点开始
- 如果el是
字符串
, 则通过document.querySelect()获取节点
, 如果没有获取到元素则新建一个div
元素返回. - 如果el是
元素
, 则不处理直接返回
el = el && query(el)
function query(el) {
if(typeof el === "string") {
var selected = document.querySelect(el)
if(!selected) {
return document.createElement("div")
}
return selected
} else {
return el
}
}
然后判断 el 不能为 body,html,因为挂载的时候会整体替换
if(el === document.body || el === document.documentElement) {
return this
}
接下来开始创建VNODE,优先用render
函数,否则使用template
if(!options.render) {
if(template) {
...
}
}
当即没render也没有template时,把el的outerHTML
作为template
template = el.outerHTML
传入的 template 可以是字符串元素
,可以是id选择器
,也可以是元素节点
- 字符串元素
template: "<div></div>"
-
含有内容的id选择器 / 元素节点 , 这2种方式都要求必须有子元素节点,因为会读取元素的
innerHTML
- id选择器
// template = "#app" if(template.charAt(0) == "#") { template = document.querySelect(template).innerHTML }
- 元素节点
if(template.nodeType) { template = template.innerHTML }
最后把 template 转换为 render函数之后,把他们添加到 options 中并开始挂载, 篇幅有限单独分析 render函数的转换
var ref = compileToFunctions(template,{...})
var render = ref.render
var staticRenderFns = ref.staticRenderFns
options.render = render
options.staticRenderFns = staticRenderFns
return mount.call(this,el)