watch监视数据的变化

vue2和vue3 watch的写法区别

  • 从vue2的配置项变成了vue3的函数
  • Vue3函数式写法,要先把watch函数imoport(同样,computed、ref、reatcive也要import)
1
import {ref,watch} from 'vue'

Watch能监视以下四种数据

  1. ref定义的数据
  2. reactive定义的数据
  3. 函数返回一个值(getter函数)
  4. 一个包含上述内容的数组

五种监视情况

情况一:监视ref定义的【基本类型】数据

  • 参数是ref数据,而不是数据的值,所以不要加.valu
  • 一共两个参数,第一个是监视的数据,第二个是回调函数,用箭头函数来写
1
2
3
4
5
6
7
8
9
10
11
12
13
<script lang="ts" setup name="Person">
import {ref,watch} from 'vue'
// 数据
let sum = ref(0)
// 方法
function changeSum(){
sum.value += 1
}
// 监视,情况一:监视【ref】定义的【基本类型】数据
watch(sum,(newValue,oldValue)=>{
console.log('sum变化了',newValue,oldValue)
})
</script>
  • 可以声明一个变量 stopWatch 来存储 watch 返回的取消观察函数,用来停止观察变化
1
2
3
4
5
6
7
8
9
10
11
12
13
<script lang="ts" setup name="Person">
import {ref,watch} from 'vue'
let sum = ref(0)
function changeSum(){
sum.value += 1
}
const stopWatch = watch(sum,(newValue,oldValue)=>{
console.log('sum变化了',newValue,oldValue)
if(newValue >= 10){
stopWatch()
}
})
</script>

情况二:监视ref定义的【对象类型】数据

  • 监视【ref】定义的【对象类型】数据,监视的是对象的地址值
  • 若想监视对象内部属性的变化,需要手动开启深度监视

    watch的第一个参数是:被监视的数据
    watch的第二个参数是:监视的回调
    watch的第三个参数是:配置对象(deep、immediate等等…..)

  • deep:true//能监视到对象里属性的变化,不写只能监视到整个对象变化
  • immediate:true//能在还没变化时就执行,监视,oldvalue此时是undefined
1
2
3
4
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{deep:true})

情况三:监视reactive定义的【对象类型】数据,且默认开启了深度监视。

  • reactive`定义的【对象类型】数据不能一下修改整个对象,需要用Object.assign(obj1,obj2)来修改。
  • 不过Object.assign改的是对象里的一个一个属性,并没有改地址值,所以oldvalue和newvalue的值也是相同的。
  • 默认开启的深度监视是不可关闭的。
1
2
3
4
5
6
7
// 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
})
watch(obj,(newValue,oldValue)=>{
console.log('Obj变化了',newValue,oldValue)
})

情况四:监视refreactive定义的【对象类型】数据中的某个属性

  • 注意点如下:

    1. 若该属性值不是【对象类型】,需要写成函数形式。
    2. 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
  • 结论:监视的要是对象里的属性,那么最好写函数式,

  • 注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。(ref定义的对象类型,reactive定义的自带)

1
2
3
4
5
6
7
8
9
10
// 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
/* watch(()=> person.name,(newValue,oldValue)=>{
console.log('person.name变化了',newValue,oldValue)
}) */

// 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数
watch(()=>person.car,(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})

  • ()=>person.name()=>{return person.name}的缩写
  • person.car因为是对象类型的属性,所以可以直接用作参数

情况五:监视多个数据

  • 用数组的方式就行
1
2
3
4
// 监视,情况五:监视上述的多个数据
watch([()=>person.name,person.car],(newValue,oldValue)=>{
console.log('person.car变化了',newValue,oldValue)
},{deep:true})