1️⃣ watch 的使用和几种情况
2️⃣ 情况一:侦听单个 ref 的响应式数据
侦听单个 ref 数据直接作为第一个参数传入
setup() {let num = ref(100);watch(num,(newValue, oldValue) => {console.log(`new:${newValue}`);console.log(`old:${oldValue}`);},{ immediate: true });return { num1, num2 };},
2️⃣ 情况二:侦听多个 ref 的响应式数据
侦听多个 ref 数据时参数为数组模式
setup() {let num1 = ref(100);let num2 = ref(200);watch([num1, num2],(newValue, oldValue) => {console.log("new", newValue);console.log("old", oldValue);},{ immediate: true });return { num1, num2 };},
2️⃣ 情况三:侦听 reactive 响应式数据
箭头 reactive 定义的响应式数据
1. 若 watch 侦听的是 reactive 定义的响应式数据,则无法正确获得 oldValue1. 下面例子中 oldValue 和 newValue 的值是一样的2. 若 watch 侦听的是 reactive 定义的响应式数据,则强制开启深度侦听1. 下面例子中更高数据的最深层次依旧可以被 watch 侦听到3. 原因:可能是因为 reactive 使用的是 proxy 封装的响应式数据,所以 reactive 的数据的 oldValue 和 newValue 是一样的,而 proxy 本身就是深度的,所以在 Vue3 中 watch 侦听 reactive 数据就是深度的
setup() {let msg = reactive({num1: 100,num2: 200,obj1: {obj2: {num3: 300,},},});watch(msg,(newValue, oldValue) => {console.log("new", newValue);console.log("old", oldValue);},{ immediate: true });return { msg };},
2️⃣ 情况四:侦听 reactive 响应式数据中的单个非对象数据
侦听 reactive 响应式数据中的单个非对象数据直接作为第一个参数传入
setup() {let msg = reactive({num1: 100,num2: 200,obj1: {obj2: {num3: 300,},},});watch(() => msg.num1,(newValue, oldValue) => {console.log("new", newValue);console.log("old", oldValue);});return { msg };},
2️⃣ 情况五:侦听 reactive 响应式数据中的单个对象数据
根据情况三的原因,Vue3 中使用的是 proxy 所以 reactive 响应式数据本身就是深度的,但是 proxy 内部的对象并非是 proxy 代理的,所以在侦听 reactive 响应式数据中的单个对象数据时,这单个对象就并非是 proxy 代理的,所以并不会像直接侦听 reactive 数据一样强制开启 deep ,而是需要手动开启才可以深度侦听
setup() {let msg = reactive({num1: 100,num2: 200,obj1: {obj2: {num3: 300,},},});watch(() => msg.obj1,(newValue, oldValue) => {console.log("new", newValue);console.log("old", oldValue);},{ deep: true });return { msg };},
2️⃣ 情况六:侦听 reactive 响应式数据中多个非对象数据
侦听 reactive 响应式数据中多个非对象数据时参数为数组模式
setup() {let msg = reactive({num1: 100,num2: 200,obj1: {obj2: {num3: 300,},},});watch([() => msg.num1, () => msg.num2], (newValue, oldValue) => {console.log("new", newValue);console.log("old", oldValue);});return { msg };},
1️⃣ watch 的 value
1️⃣ watchEffect
watchEffect 使用同 watch 一样,不同的是 watchEffect 会默认配置 immediate 为 true,初始执行一次,默认初始时就会执行第一次, 从而可以收集需要监视的数据
watch 的套路是要指明监视的属性,也要指明监视的回调
watchEffect 的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
watchEffect 有点像 computed:
1. 但 computed 注重的是计算出来的值( 回调函数的返回值 ),所以必须要写返回值2. 而 watchEffect 更注重的是过程( 回调函数的函数体 ),所以不用写返回值
// watchEffect 所指定的回调中用到的数据只要发生变化 则直接重新执行回调watchEffect(()=>{// ......})
watchEffect 需要注意的是当你侦听一个对象时,即时我们修改了对象中的数据也不会触发 watchEffect ,因为 watchEffect 收集的是对象本身,而非对象的深度侦听,所以使用 watchEffect 时需直接 watchEffect 到值本身。如果我们需要侦听一个对象,推荐使用 watch。<br />一下代码中, watch 可以侦听到,watchEffect 侦听不到。
<template><div id="app"><el-button type="primary" @click="obj.a++">obj.a</el-button><el-button type="primary" @click="obj.b.c++">obj.b.c</el-button></div></template><script setup>import { reactive, watch, watchEffect } from 'vue'const obj = reactive({a: 100,b: {c: 200}})watch(obj, (newValue, lodValue) => {console.log('watch', obj);}, { immediate: true })watchEffect(() => {console.log('watchEffect', obj);})</script>






