vue watch 和 watchEffect的区别和用法

在 Vue.js 里,watchwatchEffect 都用于响应式地追踪数据变化并执行相应操作,不过它们在使用方式、应用场景等方面存在差异。

1. watch

watch 是 Vue 提供的一个选项,用于监听特定数据的变化。当监听的数据发生变化时,会触发相应的回调函数。

基本用法
<template>
  <div>
    <input v-model="message" placeholder="输入内容">
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  },
  watch: {
    message(newValue, oldValue) {
      console.log(`新值: ${newValue}, 旧值: ${oldValue}`);
    }
  }
};
</script>

在上述代码里,watch 选项监听 message 数据的变化。当 message 的值改变时,会触发回调函数,回调函数接收两个参数:newValue(新值)和 oldValue(旧值)。

监听对象属性

若要监听对象的某个属性,可使用字符串路径:

<template>
  <div>
    <input v-model="user.name" placeholder="输入姓名">
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        name: ''
      }
    };
  },
  watch: {
    'user.name'(newValue, oldValue) {
      console.log(`姓名新值: ${newValue}, 姓名旧值: ${oldValue}`);
    }
  }
};
</script>
深度监听

当需要监听对象内部属性的变化时,可使用 deep 选项:

<template>
  <div>
    <input v-model="user.name" placeholder="输入姓名">
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        name: ''
      }
    };
  },
  watch: {
    user: {
      handler(newValue, oldValue) {
        console.log('用户对象发生变化');
      },
      deep: true
    }
  }
};
</script>

2. watchEffect

watchEffect 是 Vue 3 引入的一个函数,它会立即执行传入的函数,并响应式地追踪函数内部依赖的所有响应式数据。当这些依赖的数据发生变化时,会重新执行该函数。

基本用法
<template>
  <div>
    <input v-model="message" placeholder="输入内容">
  </div>
</template>

<script setup>
import { ref, watchEffect } from 'vue';

const message = ref('');

watchEffect(() => {
  console.log(`当前消息: ${message.value}`);
});
</script>

在上述代码中,watchEffect 传入的函数会马上执行,并且会追踪 message 的变化。当 message 的值改变时,该函数会重新执行。

停止监听

watchEffect 返回一个停止函数,调用该函数可停止监听:

<template>
  <div>
    <input v-model="message" placeholder="输入内容">
    <button @click="stop">停止监听</button>
  </div>
</template>

<script setup>
import { ref, watchEffect } from 'vue';

const message = ref('');
const stop = watchEffect(() => {
  console.log(`当前消息: ${message.value}`);
});

const stopWatch = () => {
  stop();
};
</script>

3. 区别与使用场景

  • 区别
    • 语法形式watch 是一个选项,通常在组件选项中使用;watchEffect 是一个函数,在 setup 函数中使用。
    • 依赖追踪watch 需要明确指定要监听的数据;watchEffect 会自动追踪函数内部依赖的所有响应式数据。
    • 执行时机watch 只有在监听的数据发生变化时才会执行回调函数;watchEffect 会立即执行传入的函数,并且在依赖数据变化时重新执行。
  • 使用场景
    • watch:适用于需要明确知道数据变化前后的值,或者需要监听特定数据的变化。
    • watchEffect:适用于不需要明确指定依赖,只要依赖的数据变化就执行相应操作的场景。