根据 watch 的 api,我们需要了解三个地方
- 1、监听的数据改变的时,watch 如何工作
- 2、设置 immediate 时,watch 如何工作
- 3、设置了 deep 时,watch 如何工作
响应式
Vue 会把数据设置响应式,既是设置他的 get 和 set当数据被读取get被触发,然后收集到读取他的东西,保存到依赖收集器,当数据被改变,set 被触发,然后通知曾经读取他的东西进行更新
监听的数据改变的时,watch 如何工作
watch 在一开始初始化的时候,会 读取 一遍 监听的数据的值,于是,此时 那个数据就收集到 watch 的 watcher 了 然后 你给 watch 设置的 handler ,watch 会放入 watcher 的更新函数中当数据改变时,通知 watch 的 watcher 进行更新,于是 你设置的 handler 就被调用了
设置 immediate(即时) 时,watch 如何工作
当你设置了 immediate 时,就不需要在 数据改变的时候 才会触发。 而是在 初始化 watch 时,在读取了 监听的数据的值 之后,便立即调用一遍你设置的监听回调,然后传入刚读取的值
设置了 deep 时, watch 如何工作
我们都知道 watch 有一个 deep 选项,是用来深度监听的。什么是深度监听呢?就是当你监听的属性的值是一个对象的时候,如果你没有设置深度监听,当对象内部变化时,你监听的回调是不会被触发的
在说明这个之前,请大家先了解一下
当你使用 Object.defineProperty 给 【值是对象的属性】 设置 set 和 get 的时候
-
1、如果你直接改变或读取这个属性 ( 直接赋值 ),可以触发这个属性的设置的 set 和 get
-
2、但是你改变或读取它内部的属性,get 和 set 不会被触发的
不设置 deep
- 1、因为读取了监听的 data 的属性,watch 的 watcher 被收集在 这个属性的 收集器中
设置了 deep
-
1、因为读取了监听的data 的属性,watch 的 watcher 被收集在 这个属性的 收集器中
-
2、在读取 data 属性的时候,发现设置了 deep 而且值是一个对象,会递归遍历这个值,把内部所有属性逐个读取一遍,于是 属性和 它的对象值内每一个属性 都会收集到 watch 的 watcher于是,无论对象嵌套多深的属性,只要改变了,会通知 相应的 watch 的 watcher 去更新,于是 你设置的 watch 回调就被触发了