vue3 watch监听器 和 watchEffect高级监听器
【watch监听器】
watch 是监听特定的数据源(可以是多个,是多个就是数组)【这是watch的第一个参数】,或者对象,会有一个单独的回调执行其他操作【这是watch的第二个参数】。第三个参数放后面
第一种:监听一个或多个数据源(数组),此处展示多个
绑定两个 v-modle 分别是 message1 和 message2
<template> <div> <input type="text" v-model="message" /> <input type="text" v-model="message2" /> </div> </template>
Ts 代码部分
let message = ref<string>("一"); // 第一个参数 是监听的数据, 第二个参数是一个回调函数,且回调函数里面也有两个参数(newvalue,oldvalue),可以log两个参数看区别 // 也可以监听多个数据源,第一个参数【改成数组】即可 let message2 = ref<string>("二"); watch([message, message2], (newvalue, oldvalue) => { console.log("new:", newvalue); console.log("old:", oldvalue); });
message1 里输入 1 ,对应log如下
message2 里 输入 2 ,对应log如下
第二种,监听数据源为一个对象
ts:
let person = ref({ haed: { eyes: { howBig: 4, }, }, body: { leg: { lenth: 110, }, }, }); watch(person, (newvalue, oldvalue) => { console.log("对象监听new:", newvalue); console.log("对象监听old:", oldvalue); });
html:
<input type="text" v-model="person.haed.eyes.howBig" />
显示为对象里面对应的数据为4,但input 输入内容后,发现并没有监听到
原因很简单,就是开头没有说的,现在还没有设置 watch 的【第三个参数】,设置 deep:true ,则开启了深度监听,如下所示。
watch( person, (newvalue, oldvalue) => { console.log("对象监听new:", newvalue); console.log("对象监听old:", oldvalue); }, { deep: true, } );
在input框里面的 4 后面输入 6,控制台如下,但目前有个bug(截至此稿发布时尚未修复)。oldvalue 和 newvalue的值是一样的,正常来讲oldvalue 应该是 原值为 4
此外,若希望直接调用一次,则在deep:ture所在的第三个参数对象里面 输入
immediate:true //是否立即调用一次
三. watch 监听 ref 和 reactive 的区别
watch 监听 ref 和 reactive 的区别是,watch 需要 开启深度监视 才能监听到 ref 的深层的数据,
reactive 则不需要。如下
let person = reactive({ haed: { eyes: { howBig: 4, }, }, body: { leg: { lenth: 110, }, }, }); watch( person, (newvalue, oldvalue) => { console.log("对象监听new:", newvalue); console.log("对象监听old:", oldvalue); }, );
// 如果只想监听 person 里面的其中一个 ,如 只需监听 person.body.leg.lenth 则如下 watch(()=>person.body.leg.lenth, (newvalue, oldvalue) => { console.log("对象监听new:", newvalue); console.log("对象监听old:", oldvalue); });
【watchEffect高级监听器】
watchEffect 里面 有一个回调函数 watchEffect(()=>{}) 将需要监听的值 直接塞进去完事
watchEffect 是非惰性的,打开页面就会立即执行
<div> <input type="text" v-model="msg" /> <input type="text" v-model="msg2" /> </div>
let msg = ref<string>("梅西"); let msg2 = ref<string>("内马尔"); // watchEffect 里面 有一个回调函数 watchEffect(()=>{}) 将需要监听的值 直接塞进去完事 watchEffect(() => { console.log("msg的值:", msg.value); console.log("msg2:", msg2); });
控制台:
加入 before 回调函数(自己取名)
watchEffect((before) => { console.log("msg的值:", msg.value); console.log("msg2:", msg2); before(() => { console.log("先执行的 before 回调"); }); });
在第一个 input 框内 输入 1,控制台如下
可以看到 before 不是非惰性,无法立即执行,且执行优先级更高
因此可以用before的特殊属性做些事情 如下 停止当前 watchEffect 监听
<button @click="stopWatch">停止监听</button>
const stop = watchEffect((before) => { console.log("msg的值:", msg.value); console.log("msg2:", msg2); before(() => { console.log("停止了监听"); }); }); const stopWatch = () => stop();