快捷搜索: 长连接 前端 源码 pan

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();
经验分享 程序员 微信小程序 职场和发展