在Vue-cli初始化的项目中进行测试。
使用插值表达式
tester/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>tester</title>
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<div>{{msgTestRender}}</div>
</div>
<!-- built files will be auto injected -->
</body>
</html>
页面预览
main.js
import Vue from 'vue'
Vue.config.productionTip = false
new Vue({
el: '#app',
data () {
return {
msg: 'hello world',
msgTestRender: 'hello world test render'
}
}
})
不使用插值表达式,手写render
我们在平时的开发工作中手写 render
方法的场景比较少,而写的比较多的是 template
模板, mounted
方法会把 template
编译成 render
方法。
import Vue from 'vue'
import App from './App'
import router from './router'
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
页面效果
main.js
import Vue from 'vue'
Vue.config.productionTip = false
new Vue({
el: '#app',
render (createElement) {
return createElement('div', {
attrs: {
id: '#appTest'
}
}, this.msgTestRender)
},
data () {
return {
msg: 'hello world',
msgTestRender: 'hello world test render'
}
}
})
总结
Vue 通过 $mount
实例方法挂载 vm
的,$mount
方法在多个文件中都有定义。
因为 $mount
这个方法的实现是和平台、构建方式都相关的。
例如:原型上的 $mount
方法在 src/platform/web/runtime/index.js
中定义,这么设计是为了复用,它可以被 runtime only
版本的 Vue 直接使用的。
$mount
对 el
做了限制,Vue 不能挂载在 body
、html
这样的根节点上,是因为挂载的元素是去替换页面中的元素,不是插入内容,body,HTML这些元素不能替换。
在 Vue 2.0 版本中,所有 Vue 的组件的渲染最终都需要 render
方法。
无论我们是用单文件 .vue 方式开发组件,还是写了 el
或者 template
属性,最终都会转换成 render
方法。
这个过程是 Vue 的一个“在线编译”的过程,它是调用 compileToFunctions
方法实现的。最后,调用原型上的 $mount
方法挂载。
如果没有定义 render
方法,则会把 el
或者 template
字符串转换成 render
方法。
Vue 的 _render
方法是实例的一个私有方法,它通过执行 createElement
方法,把实例渲染成一个虚拟 Node。
Vue 2.0 相比 Vue 1.0 最大的升级就是利用了 Virtual DOM。
render相关定义在源码 src/core/instance/render.js。
参考:
https://ustbhuangyi.github.io/vue-analysis/v2/data-driven/render.html