Vue学习记录之四(watch侦听器和watchEffect高级侦听器)
watch
watch 用于侦听特定的响应式数据源(如数据、计算属性等),比如ref或者是reactive时,并在其变化时执行回调函数。它适合用于处理副作用,如 API 请求或异步操作。使用 watch 适合特定数据变化的侦听,提供更细粒度的控制。
import { ref, watch } from 'vue';
const count = ref(0);
//watch第一个参数是侦听的数据源
// 第二个参数是一个回调函数 ()=>{},该回调函数有2个参数,一个是新值,另外一个旧值。
// 如果想侦听多,可以使用数组 watch([,,],(newValue, oldValue)=>{}),数组中有几个元素,就会出现几组newValue和oldValue
// 也可以监听对象,但是需要用到第三个参数,watch(数据源,(new,old)=>{},{deep: true}) 深度侦听。 而且如果是引用类型,监听到新值和旧值是一样的,
//ref中需要起开deep,reactive不需要,自动会开启deep
//如果只想侦听某个对象的某个属性,可以将属性转化为对象,如()=>message.foo.bar.name,将他作为侦听源。
//watch 第四个参数,immediate,默认的是false,开启后,只要运行就输出一次,即使没有发生改变。
// 第五个参数:flush, 默认的是pre. 是组件更新之前调用,值为sync 同步执行,值为post 组件更新之后执行。
watch(count, (newValue, oldValue) => {
console.log(`Count changed from ${oldValue} to ${newValue}`);
});
watchEffect
watchEffect 用于自动追踪其内部使用的响应式状态。它适合用于需要依赖多个数据源的场景,并会在任何相关数据变化时重新运行。使用 watchEffect 更方便,适用于动态依赖的场景,可以自动追踪相关数据。
import { ref, watchEffect } from 'vue';
const count = ref(0);
const doubleCount = ref(0);
// watchEffect 接收一个回调函数 ()=>{}, 把侦听的值直接放里面就可以。
// 参数可以接受一个回调函数,在监听之前做一些事。
// 还可以停止监听,watchEffect返回值是一个函数,直接调用就可以停止监听。
watchEffect(() => {
doubleCount.value = count.value * 2;
console.log(`Double count is now: ${doubleCount.value}`);
});
实例
<template>
<div>
<input v-model="message" type="text" /> <br>
<input v-model="message2" type="text" /><br>
</div>
</template>
<script setup lang='ts'>
import { ref,reactive, watchEffect } from 'vue'
let message = ref<string>("大飞机")
let message2 = ref<string>("小飞机")
watchEffect((oninvalidate)=>{
// 它是非惰性的,一进入页面,先给调用一次。
console.log("message",message.value)
console.log("message2",message2.value)
oninvalidate(()=>{
console.log("执行之前可以进行一些操作")
})
})
</script>
停止监听
<template>
<div>
<input v-model="message" type="text" /> <br>
<button @click="stopWatch">停止监听</button>
</div>
</template>
<script setup lang='ts'>
import { ref,reactive, watchEffect } from 'vue'
let message = ref<string>("大飞机")
const stop = watchEffect((oninvalidate)=>{
console.log("message",message.value)
oninvalidate(()=>{
console.log("执行之前可以进行一些操作")
})
})
const stopWatch = () =>stop()
</script>
更多配置项:副作用刷新时机flush, 有三个可选值,一般为 post
- post: 组件更新后执行
- pre: 组件更新前执行
- sync: 强制效果,始终同步触发
<template>
<div>
<input id="ipt" v-model="message" type="text" /> <br>
<button @click="stopWatch">停止监听</button>
</div>
</template>
<script setup lang='ts'>
import { ref,reactive, watchEffect } from 'vue'
let message = ref<string>("大飞机")
const stop = watchEffect((oninvalidate)=>{
//提示可能为null,我们来个断言(不能将类型“HTMLInputElement | null”分配给类型“HTMLInputElement”。)
let ipt:HTMLInputElement = document.querySelector("#ipt") as HTMLInputElement
//console.log("message",message.value)
console.log(ipt,"eeeeeeeeeeee")
oninvalidate(()=>{
console.log("执行之前可以进行一些操作")
})
},{
//flush属性有三个选项:post,pre,sync
flush:"post",
// 开发环境帮我们调试程序
onTrigger(e){
debugger
}
})
const stopWatch = () =>stop()
</script>