vue中watch和computed为什么能监听到数据的改变以及(3)

watch:模板获取数据时,触发其getter函数,将watcher添加到对应的Dep.subs中,在之后setter被调用时,Dep.notify通知所有watcher进行update,最终调用watcher.cb,也就是调用对应回调函数。

3、Watcher

构造函数在是watch时,会最后调用this.get,会触发属性的getter函数,将该Watcher添加到Dep的subs中,用于通知数据变动时调用。

调用Watcher实例的update方法会触发其run方法,run方法中会调用触发函数。其depend方法会调用new Dep的depend方法,dep的depend会调用Watcher的addDep方法,最终会把该watcher实例添加到Dep的subs属性中

/** *观察者解析表达式,收集依赖项, *并在表达式值更改时激发回调。 *这用于$watch()api和指令。 */ var Watcher = function Watcher ( vm, expOrFn, cb, options, isRenderWatcher ) { this.vm = vm; ...... this.cb = cb;//触发函数 this.id = ++uid$2; // uid for batching this.active = true; this.dirty = this.lazy; // for lazy watchers ...... this.value = this.lazy ? undefined ? this.get();//computed会返回undefined,而watch会执行Watcher.get }; /** * Scheduler job interface. * Will be called by the scheduler. * 该方法会执行触发函数 */ Watcher.prototype.run = function run () { if (this.active) { var value = this.get(); if ( value !== this.value || // Deep watchers and watchers on Object/Arrays should fire even // when the value is the same, because the value may // have mutated. isObject(value) || this.deep ) { // set new value var oldValue = this.value; this.value = value; if (this.user) { try { this.cb.call(this.vm, value, oldValue); } catch (e) { handleError(e, this.vm, ("callback for watcher \"" + (this.expression) + "\"")); } } else { this.cb.call(this.vm, value, oldValue); } } } }; /** * Evaluate the getter, and re-collect dependencies. */ Watcher.prototype.get = function get () { pushTarget(this); var value; var vm = this.vm; try { value = this.getter.call(vm, vm); } catch (e) { if (this.user) { handleError(e, vm, ("getter for watcher \"" + (this.expression) + "\"")); } else { throw e } } finally { // "touch" every property so they are all tracked as // dependencies for deep watching if (this.deep) { traverse(value); } popTarget(); this.cleanupDeps(); } return value }; /** * Subscriber interface. * Will be called when a dependency changes. * 在方法中调用Watcher的run方法 */ Watcher.prototype.update = function update () { /* istanbul ignore else */ if (this.lazy) { this.dirty = true; } else if (this.sync) { this.run(); } else { queueWatcher(this);//该方法最终也会调用run方法 } }; /** * Depend on all deps collected by this watcher.会调用new Dep的depend方法,dep的depend会调用Watcher的addDep方法 */ Watcher.prototype.depend = function depend () { var i = this.deps.length; while (i--) { this.deps[i].depend(); } }; /** * Add a dependency to this directive. */ Watcher.prototype.addDep = function addDep (dep) { var id = dep.id; if (!this.newDepIds.has(id)) { this.newDepIds.add(id); this.newDeps.push(dep); if (!this.depIds.has(id)) { dep.addSub(this); } } };

总结

以上所述是小编给大家介绍的vue中watch和computed为什么能监听到数据的改变以及不同之处,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3671e3e12ef5cbb747c119e02cd435f4.html