當用戶指定了watch
中的deep屬性為true
時,如果當前監控的值是數組類型。會對對象中的每一項進行求值,此時會將當前watcher
存入到對應屬性的依賴中,這樣數組中對象發生變化時也會通知數據更新
對應源碼
1 get () { 2 pushTarget(this) // 先將當前依賴放到 Dep.target上 3 let value 4 const vm = this.vm 5 try { 6 value = this.getter.call(vm, vm) 7 } catch (e) { 8 if (this.user) { 9 handleError(e, vm, `getter for watcher "${this.expression}"`) 10 } else { 11 throw e 12 } 13 } finally { 14 if (this.deep) { // 如果需要深度監控 15 traverse(value) // 會對對象中的每一項取值,取值時會執行對應的get方法 16 } 17 popTarget() 18 } 19 return value 20 } 21 function _traverse (val: any, seen: SimpleSet) { 22 let i, keys 23 const isA = Array.isArray(val) 24 if ((!isA && !isObject(val)) || Object.isFrozen(val) || val instanceof VNode) { 25 return 26 } 27 if (val.__ob__) { 28 const depId = val.__ob__.dep.id 29 if (seen.has(depId)) { 30 return 31 } 32 seen.add(depId) 33 } 34 if (isA) { 35 i = val.length 36 while (i--) _traverse(val[i], seen) 37 } else { 38 keys = Object.keys(val) 39 i = keys.length 40 while (i--) _traverse(val[keys[i]], seen) 41 } 42 }