watch在vue3中的使用

184 阅读2分钟

watch监听

监听基础类型

监听单个ref数据

使用ref绑定数据 改变值的时候需要.value

import { ref } from 'vue'
const num = ref(0)
setTimeout(() => {
   num.value = 1
}, 2000)
//监听num的变化
//打印到的'watch监听',1,0
watch(num, (newVal, oldVal) => {
  console.log('watch监听',newVal, oldVal)
})
监听多个ref数据
import { ref } from 'vue'
const num = ref(123)
const name = ref('hhh')
setTimeout(() => {
   num.value = 456
   name.value='jjj'
}, 2000)
//监听num的变化
//打印到的'watch监听',1,0
watch([num,name], (newVal, oldVal) => {
  console.log('watch监听',newVal, oldVal)
})

监听reactive引用类型

当监听整个对象 ,只要这个对象有任何修改,就会触发watch监听 无论是子属性(obj.name/obj.num)改变还是孙属性(obj.children.age) 都会触发监听 引用类型需要先深拷贝 不然监听不到变化

import { reactive, watch, computed } from 'vue'
const obj=reactive({
  name:'abc',
  num:1,
  children:{
  age:10
  }
})
const setObj=()=>{
  obj.name='def'
  obj.children.age=18
}
//监听引用类型时需要深拷贝 并用计算属性去接受这个值
const newObj=computed(()=>JSON.parse(JSON.stringify(obj)))
//可以拿到新值和旧值
watch(newObj,(newVal,oldVal)=>{
    console.log('监听到对象的变化',newVal,oldVal)
})

监听对象单个属性

除了监听整个对象 还可以只监听对象中某个属性的变化
监听obj.name属性,那么就只有name属性发生改变才会触发监听,其他属性变化不会触发 不过写法就有些不同了** 第一个参数是回调函数**

import { reactive, watch } from 'vue'
const obj = reactive({
  name: 'abc',
  num: 1
})
const setObj = () => {
  obj.name = 'def'
}
watch(() => obj.name, (newVal, oldVal) => {
  console.log('监听到对象的变化', newVal, oldVal)
})

监听对象多个属性

import { reactive, watch } from 'vue'
const obj = reactive({
  name: 'asd',
  num: 1
})
const setObj = () => {
  obj.name = 'def'
  obj.num = 20
}
watch([() => obj.name,() => obj.num], (newVal, oldVal) => {
  console.log('监听到对象的变化', newVal, oldVal)
})

同时监听reactive对象属性和ref基本类型数据

第一个参数数组形式 返回的也是数组 引用类型也还是要computed接收他的深拷贝 不然打印到的新值旧值依然还是新值

import { reactive, watch, computed, ref } from 'vue'
const obj = reactive({
  name: 'abc',
  num: 1
})
const title = ref('aaa')
const setObj = () => {
  obj.name = 'def'
  title.value = 'bbb'
}
const newObj = computed(() => JSON.parse(JSON.stringify(obj)))
watch([title, ()=>obj.name], (newVal, oldVal) => {
  console.log('监听的多个数据改变了', newVal, oldVal)
})

深度监听

computed包裹的值必须使用.value读取
immediate 的作用就是设置是否立即执行监控,当我们将其值设置为 true 时,那么被监控的对象在初始化时就会触发一次 watch 方法,相当于页面一刷新就会触发

import { reactive, watch, computed } from 'vue'

const obj = reactive({
  name: 'zs',
  age: 14,
  brand: {
    id: 1,
    name: '宝马'
  }
})
const setObj = () => {
  obj.brand.name = '奔驰'
}
const newObj = computed(() => JSON.parse(JSON.stringify(obj)))
watch(() => newObj.value.brand, (newVal, oldVal) => {
  console.log(newVal, oldVal, '对象中的某一个值的变化')
}, {
  deep: true, // 对象深度监听
  immediate: false // 立即监听
})

如果有帮助到你的话可以点赞关注