Fe-interview: Day92:既然 Vue 通过数据劫持可以精准探测数据在具体dom上的变化,为什么还需要虚拟 DOM diff 呢?

Created on 7 Jul 2020  ·  4Comments  ·  Source: lgwebdream/FE-Interview

Vue

Most helpful comment

这题回答的内容还是太全面 感觉没理解透 希望可以更新答案 获取更一步的学习

All 4 comments

每日一题会在下午四点在交流群集中讨论,五点 Github、交流群同步更新答案

答案

前置知识: 依赖收集、虚拟 DOM、响应式系统

现代前端框架有两种方式侦测变化,一种是 pull ,一种是 push

pull: 其代表为React,我们可以回忆一下React是如何侦测到变化的,我们通常会用setStateAPI显式更新,然后React会进行一层层的Virtual Dom Diff操作找出差异,然后Patch到DOM上,React从一开始就不知道到底是哪发生了变化,只是知道「有变化了」,然后再进行比较暴力的Diff操作查找「哪发生变化了」,另外一个代表就是Angular的脏检查操作。

push: Vue的响应式系统则是push的代表,当Vue程序初始化的时候就会对数据data进行依赖的收集,一但数据发生变化,响应式系统就会立刻得知。因此Vue是一开始就知道是「在哪发生变化了」,但是这又会产生一个问题,如果你熟悉Vue的响应式系统就知道,通常一个绑定一个数据就需要一个Watcher(具体如何创建的Watcher可以先了解下Vue双向数据绑定的原理如下图)

vue 双向数据绑定原理

一但我们的绑定细粒度过高就会产生大量的Watcher,这会带来内存以及依赖追踪的开销,而细粒度过低会无法精准侦测变化,因此Vue的设计是选择中等细粒度的方案,在组件级别进行push侦测的方式,也就是那套响应式系统,通常我们会第一时间侦测到发生变化的组件,然后在组件内部进行Virtual Dom Diff获取更加具体的差异,而Virtual Dom Diff则是pull操作,Vue是push+pull结合的方式进行变化侦测的。

这题回答的内容还是太全面 感觉没理解透 希望可以更新答案 获取更一步的学习

我觉得双向数据绑定只是检测数据data的变化,而虚拟DOM是真正实现DOM更新的,这两个东西的职责完全不同的,缺一不可。所以不存在为什么还要用Vdom diff.

---一个菜鸡的浅显之见

笑哭,这种问题也有问的,一个dom节点发生改变vue的响应式机制可以直接修改就行了,如果直接修改一个数组或者直接切换一个组件呢?这里面肯定有的数据没变有的数据变了,有的组件是复用的有的是没复用的,这个时候就要用diff。就是两种场景而已。react都是同理...

Was this page helpful?
0 / 5 - 0 ratings