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 }

 

posted on 2020-06-10 16:07  ming1025  阅读(2784)  评论(0编辑  收藏  举报