Vue渲染机制
1.var app = new Vue({
2. el: '#app',
3. data: {
4. message: 'Hello Vue!'
5. }
6.})
初始化新建一个vue对象,那么这里会执行构造方法中的绑定值和方法
可以看到初始化方法_init,而_init是原型上的方法
这里可以看到最后执行了初始化的渲染,initRender,而该方法呢就是对已经挂载的el进行渲染,至此完成了初始化的渲染
故最后其实都到了render函数这里
那当data里面的数据改变了视图又应该怎么改变呢?
1.vm._watcher = new Watcher(vm, () => {
2. vm._update(vm._render(), hydrating)
3.}, noop);
从这里可以知道watcher一直在监听vm中的数据,当其状态改变的时候会执行update函数,而_render函数作为其参数被优先执行,watcher这里就相当于es5中的Object.defineproperty()当状态获取新的值是就调用set(),则可知状态改变
可知render会返回vnode也就是虚拟dom
可以看下vnode的数据结构
那么vnode和dom有什么关系呢
把Vue的实例挂载到#app
, 会调用实例里面的render方法,生成虚拟DOM。来看看什么是虚拟节点
new Vue({
render: h => {
let root = h(App)
console.log('root:', root)
return root
}
}).$mount('#app')
可知vnode中的elm属性指向真实dom的节点,故虚拟dom和dom进过比较之后可以直接替换
vue渲染过程的{{xxx}}显示的解决办法
出现这个问题的原因是渲染时为执行到js的赋值代码故其值无法正常显示
解决办法 通过自定义指令
<div id="wrap" v-cloak>
添加选择器
[v-cloak]{
display:none
}
vue实例创建完成后会把v-cloak去掉,在赋值代码未解析到时,会被隐藏
为什么template里面只有一个div,做为根元素,只有一个,入口文件里面挂在el,只有一个可以找到。