Vue3 watch和watchEffect的区别

2,930 阅读1分钟

首先watch和watchEffect都是监听器,但在写法和使用上有所区别。

引用watch和watchEffect

import { watchEffect, watch } from "vue";

watch

  1. 具有一定的惰性lazy 第一次页面展示的时候不会执行,只有数据变化的时候才会执行
  2. 参数可以拿到当前值和原始值
  3. 需要传递要侦听的内容
  4. 可以侦听多个数据的变化,用一个侦听起承载

对基本数据类型进行监听

<template>
Name: <input v-model="name" />
</template>

<script setup>
const name = ref('zhangsan')
watch(name, (curVal, prevVal) => {
    console.log(curVal, prevVal)
})
<script>

对引用类型进行监听

<template>
  Name: <input v-model="name" /> englishName: <input v-model="englishName" />
</template>

<script setup>
const nameObj = reactive({ name: "leilei", englishName: "bob" });
//监听一个数据
watch(
  () => nameObj.name,
  (curVal, prevVal) => {
    console.log(curVal, prevVal);
  }
);
//监听多个数据
watch(
  [() => nameObj.name, () => nameObj.name],
  ([curName, curEng], [prevName, curEng]) => {
    console.log(curName, curEng, "----", prevName, curEng);
    setTimeout(() => {
      stop();
    }, 5000);
  }
);
const { name, englishName } = toRefs(nameObj);
</script>

watch取消监听

const stop1 = watch(
  [() => nameObj.name, () => nameObj.name],
  ([curName, curEng], [prevName, curEng]) => {
    console.log(curName, curEng, "----", prevName, curEng);
    setTimeout(() => {
      stop();
    }, 5000);
  }
);

watch也可以变为非惰性的 立即执行的 添加第三个参数 immediate: true

watch(
  [() => nameObj.name, () => nameObj.name],
  ([curName, curEng], [prevName, curEng]) => {
    console.log(curName, curEng, "----", prevName, curEng);
    setTimeout(() => {
      stop();
    }, 5000);
  },
  {
    immediate: true,
  }
);

watchEffect

  1. 立即执行,没有惰性,页面的首次加载就会执行。
  2. 没有过多的参数,只有一个回调函数
  3. 自动检测内部代码,代码中有依赖就会执行
  4. 不需要传递要侦听的内容,会自动感知代码依赖
  5. 无法获取到原值,只能得到变化后的值
  6. 异步的操作放在这里会更加合适
watchEffect(() => {
  console.log(state.count);
  console.log(state.name);
     /*  初始化时打印:
         0
         zs
      1秒后打印:
         1
         ls
     */
});

setTimeout(() => {
  state.count++;
  state.name = "ls";
}, 1000);

watchEffect取消监听

const stop = watchEffect(() => {
  console.log(nameObj.name);
  setTimeout(() => {
    stop();
  }, 5000);
});

根据以上特征,我们可以自行选择使用哪一个监听器