Chuck Liu
Chuck Liu
@jin5354 第二点有问题,用户修改 reactive 数据不会立即触发 DOM 更新,而只是被所有订阅这个 reactive 数据的 watcher 监听到,然后稍后进行批处理,把这些监听到数据变动的 watcher 的真实数据写进 DOM。 也就是你改数据后,先不改 DOM ,过一会,等待当前的 microtask 完成之后再去批处理执行所有改 DOM 的操作。 Vue 提供这个操作并不是为了你说的去『观测 DOM 更新』,DOM modification 是实时的,DOM modification 是实时的,DOM modification 是实时的,重要的话说三遍。虽然我其实在文章里多次强调这句话。DOM...
@jin5354 哦哦,这样理解是对的。我以为你说的是 vue 去观测。
好的,非常感谢,我周末试试。 @jin5354
@Archsx > 你好,请问下你所说的“也就是你改数据后,先不改 DOM ,过一会,等待当前的 microtask 完成之后再去批处理执行所有改 DOM 的操作。”,这句话里面的“等当前的microtask完成后再去批处理执行所有修改Dom的操作”是什么意思啊?难道修改Dom的操作不就在当前的microtask里面吗?还是说其实是想说等microtask执行完之后才UIrender? -- 1. 修改Dom的操作是在 microtask 里。 2. 修改Dom的操作的 microtask 前可能还有其他多个 microtask, 所以 “等当前的microtask完成后再去批处理执行所有修改Dom的操作”
@Archsx > 还有个问题,我把文中的jsFiddle里面的代码copy下来试了一下,发现还是有上下晃动的现象发生?链接: > http://js.jirengu.com/teyohuwuvu/1/edit?html,js,output 我提供的 fiddle 不会抖动,你用的版本为 [email protected], 这一版本内部机制我并不了解。你可以探索一下。
@Ge-yuan-jun 我也是断断续续看完的,整体看完的话确实比较费神。
@ZinCode 比如最后一个收集依赖的watcher是{{a}}对应的watcher,它完成依赖订阅之后,它订阅到a属性,这没问题。可是如果不把Dep.target恢复为null,他就会一直在Dep.target上。 接下来,假如说你在页面其他地方写了个v-on,现在v-on被触发了,他的回调函数里你访问了this.b,那么就会去执行b的getter,而任何getter执行过程中都会不管三七二十一,只要Dep.target不为null,就让Dep.target订阅我自己的dep。 现在出现了{{a}}的watcher订阅了b属性。这就出错了。 所以任何一个watcher的依赖收集过程完毕之后,都会在afterGet里清空Dep.target。 其实在Vue里,Dep.target有值的情况只会是watcher在进行依赖订阅的情况,所以if Dep.target为null,getter里就直接return val就完事了。
@ZinCode 在Vue初始化阶段。 在compile里会检测出你写的v-model/v-if/:style等等Vue指令,在link阶段会将这些检测到的指令创建为真正的Directive实例,之后对这些指令按照优先级排好序,然后按优先级从高到低,依次执行他们的_bind方法。而每个Directive的_bind方法中会生成一个自己的watcher。watcher也会在此时执行依赖收集的过程。
@ZinCode 额。。我待会回寝室以后帮你看看吧
@ZinCode 我看了 这行代码不写不行的,是为了求出值并把值刷新到dom上。 在Vue里也有这个操作的,一个mvvm构造阶段完成后你得保证页面里呈现你想绑定的值,比如一个input v-model绑定到a属性,你得在Vue构造完毕时保证页面这个input里的value正确呈现为a的实际值。而**watcher只是在数据变动时才会更新dom**,所以对于这种初始阶段不是数据变动的情况,必须得手动执行更新dom的这个操作。 在Vue里也一样,指令的初始化阶段(_bind)函数中,生成watcher,绑定依赖后会[this.update(watcher.value)](https://github.com/Ma63d/vue-analysis/blob/master/vue%E6%BA%90%E7%A0%81%E6%B3%A8%E9%87%8A%E7%89%88/directive.js#L160)。不过顺序不太一样,你给的代码是先update,Vue是先watcher绑定完依赖之后再update,没啥大区别。