Vue 源码(十):Vue

接下来我们来讲下 watch,这个也是比较重要的选项。

首先,我们找到 strats,然后给它设置一个自定义的策略,同样的,它也会接收几个参数:parentVal, childVal, vm, key。

然后我们会来进行一步的检测,我们会先检测 childVal 是否有值,那么 childVal 指的是谁呢?

就是我们在 new Vue() 传过来的对象中,里面有没有 watch 的配置。

那么如果说,没有值,那么我们就会直接 return 一个对象出去。

但我所 return 出去的这个对象,和之前也是一样的:Object.create(parentVal || null)

也就是说,我们会通过 Object.create 来创建一个对象,如果说 parentVal 是有值的,那么这个对象的原型对象就是 parentVal。

如果说 parentVal 是没有值的,那我们就直接返回一个空对象出去就好了。

与此同时,我们还会来做进一步的检测,也是和之前一样,调用一个 assertObjectType(key, childVal, vm) 方法。

用来检测一下,我们当前的 childVal 是否有值。

并且,我们还会来做一层判断,如果说 parentVal === undefined,我们就直接返回 childVal。

那么,如果说 parentVal 和 childVal 同时都是有值的情况下,我们应该怎么办呢?

以上代码就是我们在处理父选项和子选项之间的合并,那么怎么理解呢?

比如说父选项的为 watch: { test: function(){} }

子选项为 watch: { test: function(){}, aaa: function(){} }

那么首先,我们定义了一个对象 res,然后把我们父选项上面的属性,也就是父选项 watch 里面的 test 函数,都挂到 res 上面去。

然后我们再通过 for in 来遍历子选项 childVal,那么 childVal 是不是有2个属性,一个 test,一个 aaa。

那么 res[key] 第一次就是 test,此时 parent 就是有值的,

那 res[key] 第二次就是 aaa,那么 parent 就是 undefined 了。

那么接下来,如果 parent 有值,那么我们就包装成一个数组,在给 parent 赋值回去。

最后,再判断,如果说 parent 有值,我们在找到子选项 childVal 里面的值,来进行一个合并。

那如果说 parent 为 undefined 呢?

那我们就会走 Array.isArray(child) ? child : [child]

child 是不是一个数组,如果是就直接返回,不是,就包装成一个数组。

最终也就是这样子了:

res = {

    test: [ function(){}, function(){} ],

    aaa: [ function(){} ]

}

所以,也就是说,我们 watch 里面的每个监听属性,其实对应的都是一个数组。

数组里面存储的,也都是回调函数callback。

那么当我们所监听的数据发生更改时,就会依次来调用它们。

这个就是子类和父类之间,watch 来监听数据的时候,不仅仅是子组件去调用 watch 里面的方法,父组件它也是会去调用的。

发布了61 篇原创文章 · 获赞 3 · 访问量 4375

猜你喜欢

转载自blog.csdn.net/weixin_43921436/article/details/103450670
vue