Vue3使用watch监听响应式数据变化的方法详解

 更新时间:2026年02月11日 08:57:54   作者:Mr Xu_  
在 Vue 3 的组合式 API(Composition API)中,watch 是一个非常核心且强大的工具,用于监听响应式数据的变化并执行相应的副作用操作,本文将结合实际代码示例,深入讲解 watch 的使用方法、参数配置、常见写法及其应用场景,需要的朋友可以参考下

引言

在 Vue 3 的组合式 API(Composition API)中,watch 是一个非常核心且强大的工具,用于监听响应式数据的变化并执行相应的副作用操作。本文将结合实际代码示例,深入讲解 watch 的使用方法、参数配置(如 deepimmediate)、常见写法及其应用场景。

一、watch 基本用法

Vue 3 中的 watch 函数用于监听响应式引用(ref)、响应式对象(reactive)或计算属性(computed)的变化。其基本语法如下:

import { watch } from 'vue'
 
watch(source, callback, options?)
  • source:要监听的数据源,可以是 ref、reactive 对象、getter 函数,或由多个上述组成的数组。
  • callback:当监听的数据发生变化时触发的回调函数,接收新值和旧值作为参数。
  • options(可选):配置选项,如 { deep: true, immediate: true }

二、常见写法与示例分析

1. 监听 ref 或 reactive 对象

const count = ref(0)
 
watch(count, (newVal, oldVal) => {
  console.log(`count 从 ${oldVal} 变为 ${newVal}`)
})

对于 reactive 对象,若只监听整个对象(而非深层属性),默认不会触发深层监听:

const user = reactive({ name: 'Alice', age: 25 })
 
// ❌ 这样不会监听到 user.name 的变化!
watch(user, (newVal, oldVal) => {
  // 不会触发
})

此时需要开启 deep: true(见下文)。

2. 使用 getter 函数监听特定属性(推荐方式)

这是最灵活、最常用的方式,尤其适用于监听 props、route 等非直接 ref 的数据。

示例 1:监听 props 中的复杂对象(如数组)

watch(
  () => props.fileList,
  (newFiles, oldFiles) => handleFiles(newFiles, oldFiles),
  { deep: true }
)
  • () => props.fileList:返回一个 getter 函数,确保能正确追踪依赖。
  • deep: true:因为 fileList 很可能是数组或对象,内部元素变化不会触发浅层监听,必须开启深度监听。
  • 回调函数接收新旧值,便于做差异处理(如上传文件列表变更)。

注意:如果 fileList 是一个数组,即使你 push 一个新文件,浅层监听也不会触发,因为数组引用未变。deep: true 能解决这个问题。

示例 2:监听路由路径变化

watch(
  () => route.path,
  (newPath) => {
    activeMenu.value = newPath
  }
)
  • route 来自 vue-routeruseRoute(),是一个响应式对象。
  • 监听 route.path 可以在用户切换页面时自动更新高亮菜单项。
  • 此处无需 deep,因为 path 是字符串(原始值),变化即触发。

三、关键配置选项详解

1.deep: true—— 深度监听

  • 作用:监听对象或数组内部属性的变化。
  • 适用场景:监听嵌套对象、数组、props 中的复杂结构。
  • 注意:性能开销较大,仅在必要时使用。
const form = reactive({
  user: { name: '', email: '' }
})
 
watch(form, (newVal) => {
  // 默认不触发
}, { deep: true }) // 开启后,user.name 变化也会触发

对于 ref 包裹的对象,watch(refObj, ..., { deep: true }) 也能深度监听。

2.immediate: true—— 立即执行

  • 作用:在侦听 器创建时立即执行一次回调。
  • 适用场景:初始化时就需要根据当前值执行逻辑(如根据路由加载数据)。
watch(
  () => route.query.id,
  (id) => {
    if (id) fetchDetail(id)
  },
  { immediate: true }
)

如果不加 immediate: true,首次进入页面时 id 存在但不会触发 fetchDetail

3. 同时监听多个源

watch([refA, refB], ([newA, newB], [oldA, oldB]) => {
  console.log('A or B changed')
})

四、watch vs watchEffect

特性watchwatchEffect
是否需要指定依赖✅ 需要显式指定❌ 自动追踪
能否访问旧值✅ 可以❌ 不能
是否立即执行默认否(可用 immediate 控制)✅ 总是立即执行
适用场景需要对比新旧值、精确控制依赖初始化 + 自动依赖追踪

通常建议优先使用 watch,因为它更明确、可控。

五、最佳实践建议

  1. 监听 props 时,始终使用 getter 写法() => props.xxx
  2. 对对象/数组变化,记得加 deep: true
  3. 需要初始化执行?加 immediate: true
  4. 避免在 watch 中修改被监听的值,可能引发无限循环
  5. 及时清理副作用(如取消请求),可在回调中返回清理函数(类似 useEffect)
watch(someRef, async (id) => {
  const cancelToken = axios.CancelToken.source()
  try {
    await axios.get(`/api/data/${id}`, { cancelToken: cancelToken.token })
  } catch (e) {
    if (!axios.isCancel(e)) throw e
  }
  // 返回清理函数
  return () => cancelToken.cancel()
})

六、总结

watch 是 Vue 3 组合式 API 中处理副作用和响应式数据联动的核心工具。通过合理使用 deepimmediate 等选项,我们可以精准控制监听行为,提升应用的响应性和用户体验。

以上就是Vue3使用watch监听响应式数据变化的方法详解的详细内容,更多关于Vue3 watch监听响应式数据变化的资料请关注脚本之家其它相关文章!

相关文章

  • Vue全局事件总线和订阅与发布使用案例分析讲解

    Vue全局事件总线和订阅与发布使用案例分析讲解

    在 vue 里我们可以通过全局事件总线来实现任意组件之间通信,它的原理是给 Vue 的原型对象上面添加一个属性。这样的话我所有组件的都可以访问到这个属性,然后可以通过这个属性来访问其他组件给这个属性上面绑定的一些方法,从而去传递数据
    2022-08-08
  • vuex中五大属性和使用说明(包括辅助函数)

    vuex中五大属性和使用说明(包括辅助函数)

    这篇文章主要介绍了vuex中五大属性和使用说明(包括辅助函数),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 关于nuxt store中保存localstorage的问题

    关于nuxt store中保存localstorage的问题

    这篇文章主要介绍了关于nuxt store中保存localstorage的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 解决vue3项目打包后部署后某些静态资源图片不加载问题

    解决vue3项目打包后部署后某些静态资源图片不加载问题

    这篇文章主要给大家介绍了如何解决vue3项目打包后部署后某些静态资源图片不加载问题,文中通过图文结合的方式讲解的非常详细,有需要的朋友可以参考下
    2024-05-05
  • vue中选中多个选项并且改变选中的样式的实例代码

    vue中选中多个选项并且改变选中的样式的实例代码

    这篇文章主要介绍了vue中选中多个选项并且改变选中的样式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • vue 多入口文件搭建 vue多页面搭建的实例讲解

    vue 多入口文件搭建 vue多页面搭建的实例讲解

    下面小编就为大家分享一篇vue 多入口文件搭建 vue多页面搭建的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • Vue 3需要避免的错误

    Vue 3需要避免的错误

    Vue3已经稳定了相当长一段时间了。许多代码库都在生产环境中使用它,其他人最终都将不得不迁移到Vue3。我现在有机会使用它并记录了我的错误,下面这些错误你可能想要避免
    2023-03-03
  • vue实现搜索小功能

    vue实现搜索小功能

    这篇文章主要为大家详细介绍了vue实现搜索小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • vue实现公告消息横向无缝循环滚动

    vue实现公告消息横向无缝循环滚动

    这篇文章主要为大家详细介绍了vue实现公告消息横向无缝循环滚动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • vue动态添加背景图简单示例

    vue动态添加背景图简单示例

    这篇文章主要给大家介绍了关于vue动态添加背景图的相关资料,在一些场景下我们需要使用户可以进行自定义背景图片,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2023-07-07

最新评论