在Vue中实现深度监听的示例代码

 更新时间:2025年03月03日 09:25:42   作者:2301_76303308  
在 Vue 中,深度监听是指监听一个对象或数组的嵌套属性(深层结构)的变化,而不仅仅是监听顶层属性的引用变化,本文给大家介绍了如何在Vue中实现深度监听,并通过代码示例介绍的非常详细,需要的朋友可以参考下

一、什么是深度监听?

在 Vue 中,深度监听是指监听一个对象或数组的嵌套属性(深层结构)的变化,而不仅仅是监听顶层属性的引用变化。Vue 的响应式系统默认只监听对象的浅层属性(即直接属性),如果需要监听对象内部的嵌套属性变化,就需要启用 深度监听。

二、实现深度监听的方法

Vue 提供了 watch 选项(或 @watch 装饰器)来监听数据变化,通过设置 deep: true 可以实现深度监听。以下是具体实现方式:

1. 使用 watch 选项

语法

watch: {
  // 监听的对象
  obj: {
    handler(newVal, oldVal) {
      console.log('obj 变化了:', newVal, oldVal);
    },
    deep: true // 开启深度监听
  }
}

完整示例

new Vue({
  el: '#app',
  data() {
    return {
      obj: {
        a: 1,
        b: {
          c: 2
        }
      }
    };
  },
  watch: {
    obj: {
      handler(newVal, oldVal) {
        console.log('obj 更新:', newVal);
      },
      deep: true
    }
  },
  methods: {
    changeObj() {
      this.obj.b.c = 3; // 修改深层属性
    }
  }
});
    • 效果:当 obj.b.c 变为 3 时,watch 的 handler 会被触发,输出新值。
  • 说明

    • deep: true 会递归遍历 obj 的所有嵌套属性,确保任何深层变化都能触发监听。
    • handler 接收新值和旧值,但由于深层对象是引用类型,newVal 和 oldVal 可能是同一个对象(仅内容不同)。

2. 使用 $watch 方法

  • 语法
this.$watch('obj', (newVal, oldVal) => {
  console.log('obj 变化:', newVal);
}, {
  deep: true
});
  • 完整示例
new Vue({
  el: '#app',
  data() {
    return {
      obj: {
        a: 1,
        b: { c: 2 }
      }
    };
  },
  mounted() {
    this.$watch('obj', (newVal, oldVal) => {
      console.log('obj 更新:', newVal);
    }, {
      deep: true
    });
  },
  methods: {
    changeObj() {
      this.obj.b.c = 3;
    }
  }
});
  • 效果:与 watch 选项相同,监听深层变化。

3. 监听特定嵌套属性(避免深度监听)

  • 原理:如果只关心某个深层属性,可以直接监听其路径,无需 deep
  • 代码
watch: {
  'obj.b.c'(newVal, oldVal) {
    console.log('obj.b.c 变化:', newVal, oldVal);
  }
}
  • 效果:仅当 obj.b.c 变化时触发,不监听其他属性。
  • 优点:性能更高,避免不必要的递归监听。

三、深度监听的工作原理

  • Vue 的响应式系统基于 Object.defineProperty(Vue 2)或 Proxy(Vue 3)。
  • 默认情况下,只有对象顶层属性被设置为响应式,嵌套属性的 setter/getter 需通过 deep: true 递归绑定。
  • 当 deep: true 启用时,Vue 会遍历对象的所有属性,添加监听器,确保深层变化可被检测。

四、注意事项

  • 性能开销
    • deep: true 会递归监听所有嵌套属性,对象越大,性能开销越高。
    • 优化建议:尽量监听具体属性(如 'obj.b.c'),或拆分数据结构。
  • 新旧值问题
    • 深度监听时,newVal 和 oldVal 是同一个引用,需深拷贝比较差异:
handler(newVal) {
  const oldVal = JSON.parse(JSON.stringify(newVal));
  // 比较逻辑
}

数组特殊情况

  • 数组的嵌套对象也支持深度监听,但数组本身的push等方法已默认响应式,无需 deep
  • 示例:
watch: {
  'arr[0].a': {
    handler(newVal) {
      console.log('arr[0].a 变化:', newVal);
    },
    deep: true
  }
}
  • Vue 3 差异
    • Vue 3 使用 Proxy,深度监听更高效,但用法一致。

五、实际应用场景

  • 表单数据:监听复杂表单对象的变化,实时校验。
watch: {
  form: {
    handler(newVal) {
      this.validateForm(newVal);
    },
    deep: true
  }
}
  • 状态管理:监听嵌套状态(如 Vuex 的 state),触发更新。
  • 动态配置:监听配置对象的变化,调整 UI。

六、面试扩展

如果面试官追问,我可以补充:

替代方案:用 computed 计算属性配合 watch

computed: {
  objComputed() {
    return JSON.stringify(this.obj); // 转为字符串比较
  }
},
watch: {
  objComputed(newVal, oldVal) {
    console.log('obj 变化:', newVal);
  }
}

性能优化:结合 immediate: true(初始触发)或防抖(debounce):

watch: {
  obj: {
    handler: _.debounce(function(newVal) {
      console.log('节流更新:', newVal);
    }, 300),
    deep: true
  }
}

七、总结

  • 核心方法watch 或 $watch 设置 deep: true
  • 推荐实践:优先监听具体属性,必要时用深度监听并优化性能。
  • 代码示例已覆盖常见场景,面试中可根据需求调整。

到此这篇关于在Vue中实现深度监听的示例代码的文章就介绍到这了,更多相关Vue深度监听内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vuex提升学习篇

    Vuex提升学习篇

    本篇文章主要介绍了Vuex提升学习篇,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 关于Vue中的计算属性和监听属性详解

    关于Vue中的计算属性和监听属性详解

    这篇文章主要介绍了关于Vue中的计算属性和监听属性详解,Vue.js模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的,在模板内放入过长的或复杂的逻辑时,会让模板过重且难以维护,需要的朋友可以参考下
    2023-05-05
  • Vue2.0+Vux搭建一个完整的移动webApp项目的示例

    Vue2.0+Vux搭建一个完整的移动webApp项目的示例

    这篇文章主要介绍了Vue2.0+Vux搭建一个完整的移动webApp项目的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • Vue中的情侣属性$dispatch和$broadcast详解

    Vue中的情侣属性$dispatch和$broadcast详解

    这篇文章主要给大家介绍了关于Vue中情侣属性$dispatch和$broadcast的相关资料,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • Vue2 this 能够直接获取到 data 和 methods 的原理分析

    Vue2 this 能够直接获取到 data 和 methods 的原理分析

    这篇文章主要介绍了Vue2 this能够直接获取到data和methods的原理分析,因为methods里的方法通过bind指定了this为new Vue的实例
    2022-06-06
  • vue-element如何实现动态换肤存储

    vue-element如何实现动态换肤存储

    这篇文章主要介绍了vue-element如何实现动态换肤存储问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Swiper在Vue2中的简单使用方法

    Swiper在Vue2中的简单使用方法

    这篇文章主要给大家介绍了关于Swiper在Vue2中的简单使用方法,swiper是一款现代化的移动端轮播组件,可以在Vue中轻松使用,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • el-form-renderer使用教程

    el-form-renderer使用教程

    本文主要介绍了el-form-renderer使用教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Vue使用v-model收集各种表单数据、过滤器的示例详解

    Vue使用v-model收集各种表单数据、过滤器的示例详解

    这篇文章主要介绍了Vue使用v-model收集各种表单数据、过滤器的示例,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • vue中如何通过函数传参数

    vue中如何通过函数传参数

    这篇文章主要介绍了vue中如何通过函数传参数问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04

最新评论