/** * Subscriber interface. * Will be called when a dependency changes. * update函数在数据更新时触发 */ update() { /* istanbul ignore else */ // 计算属性的更新 if (this.computed) { // A computed property watcher has two modes: lazy and activated. // It initializes as lazy by default, and only becomes activated when // it is depended on by at least one subscriber, which is typically // another computed property or a component's render function. if (this.dep.subs.length === 0) { // In lazy mode, we don't want to perform computations until necessary, // so we simply mark the watcher as dirty. The actual computation is // performed just-in-time in this.evaluate() when the computed property // is accessed. this.dirty = true } else { // In activated mode, we want to proactively perform the computation // but only notify our subscribers when the value has indeed changed. this.getAndInvoke(() => { this.dep.notify() }) } } // 同步更新 elseif (this.sync) { this.run() } else { // 正常的派发更新 queueWatcher(this) } } }
exportfunctionqueueWatcher(watcher: Watcher) { const id = watcher.id; // 判断watcher在不在queue里面 // 即使一个watcher在一个tick内多次触发update,也不会造成多次更新 if (has[id] == null) { has[id] = true; if (!flushing) { queue.push(watcher) } else { // if already flushing, splice the watcher based on its id // if already past its id, it will be run next immediately. // 如果正在刷新 let i = queue.length - 1; while (i > index && queue[i].id > watcher.id) { i-- } queue.splice(i + 1, 0, watcher) } // queue the flush if (!waiting) { waiting = true; // 在下一个tick去执行 nextTick(flushSchedulerQueue) } } }