Vue3中我的Watch为什么总监听不到数据详解

 更新时间:2026年03月12日 09:37:08   作者:该换个名儿了  
这篇文章主要介绍了Vue3中Watch为什么总监听不到数据的相关资料,文中还分析了Vue3中的watch监听函数和直接监听对象的区别,通过代码介绍的非常详细,需要的朋友可以参考下

前言

vue3中, watch使用 watch(()=>xxx,v=>{})或者watch(xxx,val=>{})时, 总是遇到函数写法的watch监听,数据改变后没有监听到数据改变;非函数的写法反而可以监听到。

在 Vue 3 中,这两种 watch 的使用方式确实有重要区别:

1. 语法区别

// 方式一:使用函数
watch(() => obj.property, (val) => {
  console.log('值变化了:', val)
})

// 方式二:直接监听响应式对象
watch(obj, (val) => {
  console.log('对象变化了:', val)
})

2. 关键区别

方式一: 函数() => xxx

  • 监听特定属性:只追踪 obj.property 这个具体的值
  • 浅层监听:只有当 obj.property 的值本身发生变化时才触发
  • 不追踪对象引用:不关心整个 obj 对象的变化

方式二:直接监听响应式对象xxx

  • 监听整个对象:追踪对象的所有属性变化
  • 深层监听:默认深度监听对象内部所有嵌套属性的变化
  • 追踪引用变化:也会监听对象本身的重新赋值

3. 为什么有时候 "函数的写法监听不到?"

情况一:嵌套对象属性变化

const obj = reactive({ 
  nested: { 
    value: 1 
  } 
})

// ❌ 监听不到 nested.value 的变化
watch(() => obj.nested, (val) => {
  console.log('不会触发')
})

// ✅ 需要深度监听
watch(() => obj.nested, (val) => {
  console.log('会触发')
}, { deep: true })

// ✅ 或监听具体属性
watch(() => obj.nested.value, (val) => {
  console.log('会触发')
})

情况二:数组操作

const arr = reactive([1, 2, 3])

// ❌ 监听不到 push/pop 等操作
watch(() => arr.length, (val) => {
  console.log('可能不会触发')
})

// ✅ 直接监听数组
watch(arr, (val) => {
  console.log('会触发')
})

情况三:解构丢失响应性

const obj = reactive({ x: 1, y: 2 })

// ❌ 解构会丢失响应性
const { x } = obj
watch(x, (val) => { }) // 无效

// ✅ 使用 getter 函数
watch(() => obj.x, (val) => {
  console.log('会触发')
})

4. 实践建议

使用函数() => xxx的场景:

  • 监听基本类型值(string, number, boolean)
  • 监听对象的特定属性
  • 需要计算或组合的依赖
  • 避免不必要的深度监听
// 监听特定属性
watch(() => user.name, (name) => {
  console.log('用户名变化:', name)
})

// 监听计算值
watch(() => x.value + y.value, (sum) => {
  console.log('和变化:', sum)
})

使用直接监听xxx的场景:

  • 需要监听对象所有变化
  • 监听数组变化
  • 需要深度监听嵌套对象
  • 监听引用变化
// 监听整个响应式对象
watch(state, (newState) => {
  console.log('状态变化:', newState)
}, { deep: true })

// 监听数组
watch(items, (newItems) => {
  console.log('列表变化:', newItems)
})

5. 注意事项

ref对象的处理:

const count = ref(0)

// ✅ 正确:直接监听 ref
watch(count, (val) => {
  console.log('count变化:', val)
})

// ✅ 也正确:通过 .value 监听
watch(() => count.value, (val) => {
  console.log('count变化:', val)
})

reactive对象的处理:

const state = reactive({ count: 0 })

// ✅ 推荐:使用 getter 监听特定属性
watch(() => state.count, (val) => {
  console.log('count变化:', val)
})

// ⚠️ 注意:直接监听 reactive 对象会自动开启深度监听
watch(state, (val) => {
  console.log('state变化:', val) // 任何嵌套属性变化都会触发
})

总结

选择哪种方式主要取决于:

  1. 监听粒度:需要监听整个对象还是特定属性
  2. 性能考虑:避免不必要的深度监听
  3. 数据类型:基本类型用 getter,复杂对象可直接监听
  4. 变化类型:需要监听引用变化还是值变化

当发现监听不到变化时,检查是否是:

  • 嵌套对象属性变化(需要 deep: true
  • 数组方法修改(直接监听数组)
  • 解构导致响应性丢失(使用函数)

到此这篇关于Vue3中Watch为什么总监听不到数据详解的文章就介绍到这了,更多相关Vue3 Watch监听不到数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue 使用v-for进行循环的实例代码详解

    vue 使用v-for进行循环的实例代码详解

    这篇文章主要介绍了vue 使用v-for进行循环的实例代码详解,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • Vue 数值改变页面没有刷新的问题解决(数据改变视图不更新的问题)

    Vue 数值改变页面没有刷新的问题解决(数据改变视图不更新的问题)

    这篇文章主要介绍了Vue 数值改变页面没有刷新的问题解决(数据改变视图不更新的问题),本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • vue.js自定义组件实现v-model双向数据绑定的示例代码

    vue.js自定义组件实现v-model双向数据绑定的示例代码

    这篇文章主要介绍了vue.js自定义组件实现v-model双向数据绑定的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • vscode使用Eslint+Prettier格式化代码的详细操作

    vscode使用Eslint+Prettier格式化代码的详细操作

    这篇文章主要介绍了vscode使用Eslint+Prettier格式化代码,本文通过图文示例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • 浅析Vue中defineProps的解构和不解构

    浅析Vue中defineProps的解构和不解构

    defineProps 是 Vue 3 Composition API 中用来声明组件接收的 props 的方法,本文主要为大家介绍了defineProps的解构和不解构,感兴趣的可以了解下
    2025-02-02
  • 基于Vue的前端界面实现日期时间实时显示简单代码

    基于Vue的前端界面实现日期时间实时显示简单代码

    今天在项目中有一个功能是要求显示北京的实时时间,下面这篇文章主要给大家介绍了关于如何基于Vue的前端界面实现日期时间实时显示的相关资料,需要的朋友可以参考下
    2024-01-01
  • Vue.js实现的购物车功能详解

    Vue.js实现的购物车功能详解

    这篇文章主要介绍了Vue.js实现的购物车功能,结合实例形式分析了vue.js购物车的原理、数值计算及页面元素属性动态操作相关实现技巧,需要的朋友可以参考下
    2019-01-01
  • vue实现图片按比例缩放问题操作

    vue实现图片按比例缩放问题操作

    这篇文章主要介绍了vue实现图片按比例缩放问题操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue实现给div绑定keyup的enter事件

    vue实现给div绑定keyup的enter事件

    这篇文章主要介绍了vue实现给div绑定keyup的enter事件,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • vue 指令与过滤器案例代码

    vue 指令与过滤器案例代码

    这篇文章主要介绍了vue 指令与过滤器,本文通过案例代码给大家详细讲解,给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-11

最新评论