Vue3监听数据变化方法详解

在 Vue 3 中,监听数据变化主要依赖 watch 和 watchEffect 两个 API,它们都属于 Composition API 的一部分。以下是详细的用法和区别:


一、watch 的基本用法

作用:显式监听特定数据源,在数据变化时执行回调函数。

1. 监听单个数据源

javascript

复制

import { ref, watch } from 'vue';

const count = ref(0);

// 监听 ref
watch(count, (newVal, oldVal) => {
  console.log(`count变化: ${oldVal} → ${newVal}`);
});
2. 监听 reactive 对象的属性

javascript

复制

import { reactive, watch } from 'vue';

const state = reactive({ 
  user: { 
    name: 'Alice', 
    age: 30 
  }
});

// 监听对象属性(需用 getter 函数)
watch(
  () => state.user.age,
  (newVal, oldVal) => {
    console.log(`年龄变化: ${oldVal} → ${newVal}`);
  }
);
3. 监听多个数据源

javascript

复制

const a = ref(1);
const b = ref(2);

watch([a, b], ([newA, newB], [oldA, oldB]) => {
  console.log(`a: ${oldA}→${newA}, b: ${oldB}→${newB}`);
});
4. 深度监听(deep)

默认情况下,watch 是浅层监听。对嵌套对象需开启 deep: true

javascript

复制

watch(
  () => state.user,
  (newUser) => {
    console.log('用户信息变化(包括嵌套属性):', newUser);
  },
  { deep: true }
);
5. 立即执行(immediate)

在监听开始后立即触发回调:

javascript

复制

watch(
  count,
  (newVal) => {
    console.log('初始值:', newVal);
  },
  { immediate: true }
);

二、watchEffect 的用法

作用:自动跟踪依赖,并在依赖变化时立即执行副作用函数。

1. 基本使用

javascript

复制

import { ref, watchEffect } from 'vue';

const count = ref(0);

// 自动追踪 count 的变化
watchEffect(() => {
  console.log('当前count值:', count.value);
});
2. 自动聚合依赖

无需手动指定依赖,函数内使用的响应式变量会被自动追踪:

javascript

复制

const a = ref(1);
const b = ref(2);

watchEffect(() => {
  console.log('a + b =', a.value + b.value);
});
// 修改 a 或 b 都会触发
3. 清理副作用

通过返回一个函数来清理副作用(如定时器、事件监听):

javascript

复制

watchEffect((onCleanup) => {
  const timer = setInterval(() => {
    console.log('每秒执行');
  }, 1000);

  onCleanup(() => clearInterval(timer));
});

三、watch vs watchEffect

特性watchwatchEffect
依赖指定显式指定数据源自动追踪回调内的响应式依赖
初始执行默认不执行(可配置 immediate立即执行
适用场景需要精确控制监听的数据源依赖变化时自动执行聚合逻辑
深度监听需手动开启 deep: true自动追踪嵌套属性(类似 deep)

四、停止监听器

通过调用 watch 或 watchEffect 返回的函数来停止监听:

javascript

复制

const stop = watchEffect(() => { /* ... */ });

// 停止监听
stop();

在组件卸载时自动停止:

javascript

复制

import { onUnmounted } from 'vue';

setup() {
  const stop = watchEffect(() => { /* ... */ });
  onUnmounted(stop);
}

五、实用场景示例

1. 搜索输入防抖(watch)

javascript

复制

const searchQuery = ref('');
let timeoutId;

watch(searchQuery, (newQuery) => {
  clearTimeout(timeoutId);
  timeoutId = setTimeout(() => {
    fetchResults(newQuery);
  }, 500);
});
2. 自动保存表单(watchEffect)

javascript

复制

const form = reactive({ title: '', content: '' });

watchEffect((onCleanup) => {
  // 自动追踪 form.title 和 form.content
  const autoSave = setTimeout(() => {
    saveToServer(form);
  }, 3000);

  onCleanup(() => clearTimeout(autoSave));
});

六、注意事项

  1. 避免无限循环:在监听回调中修改被监听的数据可能导致循环,需谨慎。

  2. 性能优化:避免过度使用 deep: true,尤其是大型对象。

  3. 异步操作:在回调中进行异步操作时,使用 onCleanup 清理未完成的请求。

掌握这些技巧后,你可以更灵活地利用 Vue 3 的响应式系统构建高效应用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值