采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
不能直接监听 props.data 吗?为什么要把 props.data 变成一个函数的返回值来进行监听?
不可以喔,其实这个问题可以简化:import { watch, reactive } from 'vue'const a = reactive({ b: []})watch(() => a.b, (newVal) => { console.log(newVal)})a.b = [1]这样是可以执行回调函数的,但是改成这样就不行watch(a.b, (newVal) => { console.log(newVal)})a.b = [1]之所以不行,是因为你在 watch 的时候就已经访问了 a.b,这个时候它收集依赖对应的 effect 是 render effect。而前面之所以可以,是因为 a.b 的访问延时了,watch 的 source 直接就是一个函数,然后当 a.b 真正访问的时候,这个时候收集依赖就是 watch 内部创建的 effect,这个 effect 对应的函数才会去执行回调函数 cb。这块儿可以自己去看看 watch 实现的源码,也可以参考我在拉勾的 Vue.js 3.0 源码解析课程对这块的分析。我再给你留一个问题,你好好思考一下。watch(a.b, (newVal) => { console.log(newVal)})a.b.push(1) 这样会不会执行回调,为什么。
目前我的理解是监听对象当中的属性(v2里面的深度监听), 在v3里面需要返回一个函数来监听, 监听普通的ref就可以直接写, 老师我这样理解对吗?
嗯,差不多,最好是把这块实现的源码搞清楚,这样理解更深
这样会执行回调。 去看了下老师写的源码解析,我理解的是 直接监听 a.b 的话,监听的是一个Reactive对象,在watch的内部,监听的如果是一个Reactive对象的话,会将deep属性设置为true,deep属性为true的情况下会执行traverse方法去递归访问对象深层的子属性,这次访问就会触发依赖收集,watcher创建的effect就会被收集。所以执行a.b.push(1),就能够触发这个effect,就执行了我们定义的cb。
在 traverse 的过程中,判断如果是数组,在遍历数组的过程中,访问了 value.length,这个时候触发了依赖收集,并且当前的 activeEffect 就是 watcher 内部创建的 effect。
登录后可查看更多问答,登录/注册
慕课网明星讲师黄轶深度讲解 Vue3.0 ,提升的不止是Vue代码能力
1.2k 3
538 23
2.9k 15
1.1k 14
1.2k 13