Vue.js Watch中的 deep:true 是如何实现的
当用户指定了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 }
如果我的内容能对你有所帮助,我就很开心啦!