合作联系微信: w6668263      合作联系电话:177-9238-7426     

Vue3中 watch、watchEffect 详解

Vue3中 watch、watchEffect 详解

 

 

 

1. watch 的使用

 

监听 ref 定义的响应式数据

 

<template>
  <div>
    <div>值:{{count}}</div>
    <button @click="add">改变值</button>
  </div>
</template>

<script>
import { ref, watch } from 'vue';
export default {
  setup(){
    const count = ref(0);
    const add = () => {
      count.value ++
    };
    watch(count,(newVal,oldVal) => {
      console.log('值改变了',newVal,oldVal)
    })
    return {
      count,
      add,
    }
  }
}
</script>

 

监听 reactive 定义的响应式数据

 

<template>
  <div>
    <div>{{obj.name}}</div>
    <div>{{obj.age}}</div>
    <button @click="changeName">改变值</button>
  </div>
</template>

<script>
import { reactive, watch } from 'vue';
export default {
  setup(){
    const obj = reactive({
      name:'zs',
      age:14
    });
    const changeName = () => {
      obj.name = 'ls';
    };
    watch(obj,(newVal,oldVal) => {
      console.log('值改变了',newVal,oldVal)
    })
    return {
      obj,
      changeName,
    }
  }
}
</script>

 

监听多个响应式数据数据

 

<template>
  <div>
    <div>{{obj.name}}</div>
    <div>{{obj.age}}</div>
    <div>{{count}}</div>
    <button @click="changeName">改变值</button>
  </div>
</template>

<script>
import { reactive, ref, watch } from 'vue';
export default {
  setup(){
    const count = ref(0);
    const obj = reactive({
      name:'zs',
      age:14
    });
    const changeName = () => {
      obj.name = 'ls';
    };
    watch([count,obj],() => {
      console.log('监听的多个数据改变了')
    })
    return {
      obj,
      count,
      changeName,
    }
  }
}
</script>

 

 

监听对象中某个属性的变化

 

<template>
  <div>
    <div>{{obj.name}}</div>
    <div>{{obj.age}}</div>
    <button @click="changeName">改变值</button>
  </div>
</template>

<script>
import { reactive, watch } from 'vue';
export default {
  setup(){
    const obj = reactive({
      name:'zs',
      age:14
    });
    const changeName = () => {
      obj.name = 'ls';
    };
    watch(() => obj.name,() => {
      console.log('监听的obj.name改变了')
    })
    return {
      obj,
      changeName,
    }
  }
}
</script>

 

 

深度监听(deep)、默认执行(immediate)

 

<template>
  <div>
    <div>{{obj.brand.name}}</div>
    <button @click="changeBrandName">改变值</button>
  </div>
</template>

<script>
import { reactive, ref, watch } from 'vue';
export default {
  setup(){
    const obj = reactive({
      name:'zs',
      age:14,
      brand:{
        id:1,
        name:'宝马'
      }
    });
    const changeBrandName = () => {
      obj.brand.name = '奔驰';
    };
    watch(() => obj.brand,() => {
      console.log('监听的obj.brand.name改变了')
    },{
      deep:true,
      immediate:true,
    })
    return {
      obj,
      changeBrandName,
    }
  }
}
</script>

 

 

 

 

 

2. watchEffect 的使用

 

watchEffect 也是一个帧听器,是一个副作用函数。 它会监听引用数据类型的所有属性,不需要具体到某个属性,一旦运行就会立即监听,组件卸载的时候会停止监听。

 

<template>
  <div>
    <input type="text" v-model="obj.name"> 
  </div>
</template>

<script>
import { reactive, watchEffect } from 'vue';
export default {
  setup(){
    let obj = reactive({
      name:'zs'
    });
    watchEffect(() => {
      console.log('name:',obj.name)
    })

    return {
      obj
    }
  }
}
</script>

 

 

停止侦听

当 watchEffect 在组件的 setup() 函数或生命周期钩子被调用时,侦听器会被链接到该组件的生命周期,并在组件卸载时自动停止。 在一些情况下,也可以显式调用返回值以停止侦听:

 

<template>
  <div>
    <input type="text" v-model="obj.name"> 
    <button @click="stopWatchEffect">停止监听</button>
  </div>
</template>

<script>
import { reactive, watchEffect } from 'vue';
export default {
  setup(){
    let obj = reactive({
      name:'zs'
    });
    const stop = watchEffect(() => {
      console.log('name:',obj.name)
    })
    const stopWatchEffect = () => {
      console.log('停止监听')
      stop();
    }

    return {
      obj,
      stopWatchEffect,
    }
  }
}
</script>

 

 

 

3. 总结

watch 特点

watch 监听函数可以添加配置项,也可以配置为空,配置项为空的情况下,watch的特点为:

  • 有惰性:运行的时候,不会立即执行;
  • 更加具体:需要添加监听的属性;
  • 可访问属性之前的值:回调函数内会返回最新值和修改之前的值;
  • 可配置:配置项可补充 watch 特点上的不足: immediate:配置 watch 属性是否立即执行,值为 true 时,一旦运行就会立即执行,值为 false 时,保持惰性。 deep:配置 watch 是否深度监听,值为 true 时,可以监听对象所有属性,值为 false 时保持更加具体特性,必须指定到具体的属性上。

watchEffect 特点

  • 非惰性:一旦运行就会立即执行;
  • 更加抽象:使用时不需要具体指定监听的谁,回调函数内直接使用就可以;
  • 不可访问之前的值:只能访问当前最新的值,访问不到修改之前的值;

 

 

 

 

作者:明天也要努力
链接:https://juejin.cn/post/7092412488725037087
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

 

Vue 3 watch增加了同时监听多个变量的能力,用数组表达要监听的变量。回调参数是这种结构:[newR, newS, newT], [oldR, oldS, oldT],不要理解成其他错误的结构

  • 被监听的变量必须是:A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.也就是说,可以是getter/effect函数、ref、Proxy以及它们的数组。绝对不可以是纯对象或基本数据。
  • Vue 3的深度监听还有没有?当然有,而且默认就是,无需声明。当然,前提是深层 property 也是响应式的。如果深层 property 无响应式,那么即便写上 { deep: true } 也没用。

watch() 总共接收三个参数

第一个参数是需要被监听的数据源。这个来源必须是以下几种:

  • 一个getter 函数,返回一个值
  • 一个 ref() 定义的响应式数据
  • 一个 reactive() 定义的响应式数据
  • 以及由以上类型的值组成的数组

 

第二个参数

是在监听的数据源发生变化时要调用的回调函数。这个回调函数接受三个参数:新值(newValue)、旧值(oldValue),以及一个用于注册副作用清理的回调函数。该回调函数会在副作用下一次重新执行前调用,可以用来清除无效的副作用,例如等待中的异步请求。

 
 
watch(data, (newValue, OldValue, onCleanup) => {
    console.log("数据变化了", `新值是:${newValue}`, `旧值是${OldValue}`);
    onCleanup(() => {
        console.log("清除副作用");
    });
});
当同时监听多个来源时,回调函数接受两个数组,分别对应来源数组中的新值和旧值
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
  /* ... */
})

第三个参数是一个可选参数(options 配置对象),支持以下这些配置选项:

    immediate:在侦听器创建时立即触发回调。第一次调用时旧值是 undefined
    deep:如果源是对象,强制深度遍历,以便在深层级变更时触发回调。参考深层监听器
    flush:调整回调函数的刷新时机。参考回调刷新的时机以及watchEffect()
    onTrack / onTrigger:调试侦听器的依赖。参考侦听器调试
    once:回调函数只会运行一次。侦听器将在回调函数首次运行后自动停止。【 3.4+ 版本特性 】

 
interface WatchOptions extends WatchEffectOptions {
  immediate?: boolean // 默认:false
  deep?: boolean // 默认:false
  flush?: 'pre' | 'post' | 'sync' // 默认:'pre'
  onTrack?: (event: DebuggerEvent) => void
  onTrigger?: (event: DebuggerEvent) => void
  once?: boolean // 默认:false (3.4+)
}
以上总结内容参考自:https://blog.csdn.net/qq_60961397/article/details/136493843
 

posted on 2024-10-17 10:01  草率的龙果果  阅读(138)  评论(0编辑  收藏  举报

导航