Virtual DOM
虚拟DOM是由普通的JS对象来描述DOM对象,因为不是真实的DOM对象,所以叫Virtual DOM。
创建虚拟DOM的开销要比真实DOM小很多
为什么要使用Virtual DOM
- 手动操作DOM比较麻烦,还要考虑浏览器兼容性问题,随着项目的复杂,DOM操作复杂度提升
- 为了简化DOM复杂操作出现了MVVM框架,MVVM框架解决了视图和状态的同步问题
- 为了简化视图的操作我们可以使用模板引擎,但是模板引擎没有解决跟踪状态变化的问题,于是出现了Virtual DOM
- Virtual DOM的好处是当状态改变时不需要立即更新DOM,只需要创建一个虚拟树来描述DOM,Virtual DOM内部将弄清楚如何有效的(Diff)更新DOM
- 参考github上Virtual DOM的描述
- 虚拟DOM可以维护程序的状态,跟踪上一次状态
- 通过比较前后两次状态的差异更新真实DOM
Virtual DOM的作用
- 维护视图和状态的关系,使用虚拟DOM可以记录上一次状态的变化,只更新状态变化的位置
- 复杂视图情况下提升渲染性能
- 除了渲染DOM以外,还可以实现SSR,原生应用,小程序等
- Virtual DOM 开源库
-
Snabbdom
- Vue2.x内部使用的Virtual DOM就是改造的Snabbdom
- 大约200SLOC(single line of code)
- 通过模块可扩展
- 源码使用TypeScript开发
- 最快的Virtual DOM之一
-
Virtual-dom
- 最早的虚拟DOM的开源库
-
函数重载
函数重载指的是参数个数或类型不同的函数,JavaScript没有重载的概念,TypeScript通过代码调整参数实现重载
function add (a, b) {
return a + b
}
// 由于JS没有函数重载的概念,所以后声明的同名函数会覆盖上一个函数
// 如果是支持重载的语言,可以定义两个同名的函数,通过参数个数或类型的不同来区分两个函数
//
function add (a, b, c) {
return a + b + c
}
Diff算法
Snabbdom中path(oldVnode, newVnode)用来比较新旧节点,如果新的Vnode有子节点,判断子节点是否变化,
判断子节点的过程就是Diff算法,Diff过程只进行同层级别比较
观察者模式
vue的响应式机制运用了观察者模式,观察者模式和发布订阅模式的区别是没有事件中心,
只有发布者和订阅者,同时发布者需要知道订阅者的存在
观察者模式是由具体目标调度,当事件触发时发布者会去调用观察者的方法,所以发布者与订阅者是相互依赖的
发布订阅模式由统一的调度中心(事件中心)调用,发布者与订阅者不需要知道对方的存在
-
观察者(订阅者)-- watcher
- update() 当事件发生时需要做的事情
-
目标(发布者) -- dep
- subs数组:存储所有观察者
- addSub():添加观察者
- notify():当事件发生时,调用所有观察者的update()方法
// 订阅者
class Dep {
constructor () {
// 记录所有订阅者
this.subs = []
}
addSub (sub) {
// 判断观察者是否存在,并且具有update方法
if (sub && sub.update) {
this.subs.push(sub)
}
}
notify () {
this.subs.forEach(sub => {
sub.update()
})
}
}
// 观察者
class Watcher {
update () {
console.log('update')
}
}
let dep = new Dep()
let watch = new Watcher()
dep.addSub(watch)
dep.notify()