浏览器渲染的原理图:
采用JS对象去模拟DOM结构的好处是,页面的更新完全可以映射到JS对象中去处理,而操作内存中的JS对象速度也会更快。
Vue的加载流程:
1. 每一个组件在加载时都会调用vue内部的render函数来把这个组件的template选项的模板解析为一个JS对象,这个对象跟DOM节点对象“长得一样”,就是为了后来的渲染。
Vnode:{
tag:"12sdsdf3asd",
id:109,
name:"Box",
$el:真实页面上的DOM的引用,
//等等属性
chiren:[
{
tag:"12sdsdf34asd",
id:109,
name:"Box2",
$el:真实页面上的DOM的引用,
//等等属性
},
{
tag:"162sdsdf34asd",
id:10942,
name:"Box3",
$el:真实页面上的DOM的引用,
//等等属性
},
{tag:"12sd7sdf34asd",
id:10492,
name:"Box4",
$el:真实页面上的DOM的引用,
//等等属性
}
]
}
2. 然后是数据劫持代理监听等等
- 底层有一种设计:发布/订阅设计,其实就是写了一个
watcher函数去订阅(监听)数据的改变(底层js语法,就是definedproty,vue3.0版本是proxy)
- 当数据发生变化以后:当状态(数据)变更的时候,重新构造一颗新的对象树。然后用新的树和旧的树进行比较(DIFF算法),记录两棵树差异,把第二棵树所记录的差异应用到第一棵树所构建的真正的DOM树上(patch:页面刷新),视图就更新了。(也就是将旧的VNode树与生成的新VNode树进行比较,比较差异,然后更新DOM(刷新页面),实现这个过程的代码就是DIFF算法)
疑惑:如果el和$mount都写了,会不会报错
答案:不会,而且$mount的优先级高