参考资料: 掘金小册 《剖析Vue.js内部运行机制》
<div id="app">
<div>{{ number }}</div>
<div>{{ hahaha }}</div>
</div>
<div id="app2">
<div>{{ number }}</div>
<div>{{ hahaha }}</div>
</div>
const data = {
message: 'Hello Vue!',
a: 1
}
const app = new Vue({
el: '#app',
data: data
})
const app2 = new Vue({
el: '#app2',
data: data
})
一个视图(
<div id="app">
<div>{{ number }}</div>
<div>{{ hahaha }}</div>
</div>
)对应一个watcher watcher在编译模板时候生成 watcher生成的时候会调用使用到的数据的get方法 从而将该watcher放到dep中
number: 0 dep1
msg: 'hahaha' dep2
一个数据对应一个dep
当数据改变时,会调用对应数据的set方法 从而dep.notify->watcher.update
依赖收集的结果为
dep1收集了 watcher1 watcher2
dep2收集了 watcher1 watcher2
例如: 这里number = 1 会dep1.notify->watcher1.update(视图1#app的更新),watcher2.update(视图2#app2的更新)
watcher1.update->watcher1.queueWatcher(watcher1)
三个队列
queue 用于存放watcher
callbacks 用于存放flushScdulerQueueFn【用于存放处理queue的函数】
settimeout队列【异步队列】 用于存放flushCallbacksFn【用于存放处理callbacks的函数】
queue = []
waiting = false
queueWatcher (watcher) {
queue.push(watcher) //判重加入watcher
if(!waiting) {
waiting = true
nextTick(flushScdulerQueueFn)
}
}
flushScdulerQueueFn() {
//处理queue数组中的每一项 并且调用watcher.run() 处理过的watcher从queue中移除
waiting = false
}
callbacks = []
pending = false
nextTick (cb) {
callbacks.push(cb)
if(!pending) {
pending = true
settimeout(flushCallbacksFn,0)
}
}
flushCallbacksFn () {
pending = false
// 处理callbacks数组中的每一项 并且调用flushScdulerQueueFn
}
网友评论