Vue监视数据的原理和set()的使用方法示例

 更新时间:2025年09月06日 13:53:41   作者:枫叶是圆的  
Vue.set方法用于向响应式对象中添加新的属性,并确保这个新属性是响应式的,这篇文章主要介绍了Vue监视数据的原理和set()使用方法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在 Vue 中,Vue.set()(或 this.$set())是用于解决响应式数据更新检测的重要方法,其底层与 Vue 的数据监视原理紧密相关。以下从使用场景和实现原理两方面详细说明:

一、Vue.set () 的使用场景与用法

1. 为什么需要 Vue.set ()?

Vue 的响应式系统通过 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现数据监听,但存在限制:

  • 无法检测对象新增的属性删除的属性
  • 无法检测数组通过索引修改元素修改数组长度的操作。

此时,直接修改数据不会触发视图更新,需要用 Vue.set() 强制触发响应式更新。

2. 用法

  • 语法
    // 全局方法
    Vue.set(target, propertyName/index, value)
    
    // 实例方法(组件内)
    this.$set(target, propertyName/index, value)
    
  • 参数
    • target:需要修改的响应式对象或数组(必须是已被 Vue 响应式系统劫持的对象);
    • propertyName/index:新增 / 修改的属性名(对象)或索引(数组);
    • value:对应的值。

3. 典型场景

  • 给对象新增响应式属性

    data() {
      return {
        user: { name: '张三' }
      }
    },
    methods: {
      addAge() {
        // 直接新增属性,视图不会更新
        this.user.age = 20; // 无效
        
        // 使用 $set,视图会更新
        this.$set(this.user, 'age', 20); // 有效
      }
    }
    
  • 修改数组的指定元素

    data() {
      return {
        list: ['苹果', '香蕉']
      }
    },
    methods: {
      updateItem() {
        // 直接通过索引修改,视图不会更新
        this.list[1] = '橙子'; // 无效
        
        // 使用 $set,视图会更新
        this.$set(this.list, 1, '橙子'); // 有效
      }
    }
    

二、Vue 监视数据的原理

Vue 实现数据响应式的核心是对数据进行劫持,并在数据变化时通知依赖更新视图。不同 Vue 版本的实现方式略有差异:

1. Vue 2 的响应式原理(Object.defineProperty)

  • 初始化劫持
    当组件初始化时,Vue 会遍历 data 中的所有属性,通过 Object.defineProperty 为每个属性添加 getter 和 setter

    • getter:当属性被访问时触发,用于收集依赖(记录哪些视图 / 计算属性依赖该数据)。
    • setter:当属性被修改时触发,用于通知依赖更新(触发视图重新渲染)。
  • 局限性

    • 只能劫持初始化时已存在的属性,新增属性默认没有 getter/setter,因此无法被监测。
    • 数组的 length 修改和索引赋值不会触发 setter(Vue 对数组的 7 个方法进行了重写,如 pushsplice 等,这些方法会触发更新,但直接修改索引 / 长度不会)。

2. Vue 3 的响应式原理(Proxy)

  • 初始化劫持
    Vue 3 使用 ES6 的 Proxy 对 data 对象进行代理,生成一个代理对象(Proxy)。Proxy 可以拦截对象的所有操作(包括新增属性、删除属性、索引访问等),从而解决了 Vue 2 的局限性。

  • 优势

    • 能监测新增属性proxy.xxx = value 会被 set 拦截);
    • 能监测删除属性delete proxy.xxx 会被 deleteProperty 拦截);
    • 能监测数组索引修改长度变化(通过 set 拦截)。

三、Vue.set () 的底层实现逻辑

Vue.set() 的核心作用是手动为数据添加响应式能力,并触发更新:

  • 对于对象

    • 检查目标对象是否为响应式对象(是否有 __ob__ 标识,Vue 内部用于标记响应式对象)。
    • 若属性已存在,则直接修改值并触发 setter
    • 若属性不存在,则通过 Object.defineProperty(Vue 2)或 Proxy 的 set 拦截(Vue 3)为新属性添加响应式,并手动触发依赖更新。
  • 对于数组

    • 调用数组的 splice 方法(Vue 已重写该方法,会触发更新),通过 splice(index, 1, value) 实现元素修改,从而触发视图更新。

总结

  • Vue.set () 的作用:解决 Vue 响应式系统无法检测 “对象新增属性”“数组索引修改” 等操作的问题,强制为数据添加响应式并触发视图更新。
  • 监视数据的原理
    • Vue 2 基于 Object.defineProperty 劫持属性的 getter/setter,实现依赖收集和更新通知。
    • Vue 3 基于 Proxy 代理整个对象,拦截所有操作,天然支持更多场景的监测。

理解这一机制有助于避免 “数据修改后视图不更新” 的常见问题,也能更深入地掌握 Vue 响应式系统的设计思想。

到此这篇关于Vue监视数据的原理和set()使用方法的文章就介绍到这了,更多相关Vue监视数据和set()使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue3封装AES(CryptoJS)前端加密解密通信代码实现

    vue3封装AES(CryptoJS)前端加密解密通信代码实现

    防止数据被爬取,前后端传参接收参数需要加密处理,使用AES加密,这篇文章主要给大家介绍了关于vue3封装AES(CryptoJS)前端加密解密通信代码实现的相关资料,需要的朋友可以参考下
    2023-12-12
  • 使用vue制作滑动标签

    使用vue制作滑动标签

    这篇文章主要为大家详细介绍了使用vue制作滑动标签,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • 如何利用vue.js实现拖放功能

    如何利用vue.js实现拖放功能

    这篇文章主要给大家介绍了如何利用vue.js实现拖放功能的相关资料,本文并未使用现有的库,而是使用内置的HTML拖放API来实现简单的拖放系统,需要的朋友可以参考下
    2021-06-06
  • Vue之Dep和Observer的用法及说明

    Vue之Dep和Observer的用法及说明

    这篇文章主要介绍了Vue之Dep和Observer的用法及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 关于ElementUI el-table 鼠标滚动失灵的问题及解决办法

    关于ElementUI el-table 鼠标滚动失灵的问题及解决办法

    这篇文章主要介绍了关于ElementUI el-table 鼠标滚动失灵的问题及解决办法,本文给大家分享问题所在原因及解决方案,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • vue实现可移动的悬浮按钮

    vue实现可移动的悬浮按钮

    这篇文章主要为大家详细介绍了vue实现可移动的悬浮按钮,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • 动态实现element ui的el-table某列数据不同样式的示例

    动态实现element ui的el-table某列数据不同样式的示例

    这篇文章主要介绍了动态实现element ui的el-table某列数据不同样式的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 解读Vue-loader的相关知识

    解读Vue-loader的相关知识

    这篇文章主要介绍了解读Vue-loader的相关知识,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • vue实现购物车的监听

    vue实现购物车的监听

    这篇文章主要为大家详细介绍了利用vue的监听事件实现一个简单购物车,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • vuecli4中如何配置打包使用相对路径

    vuecli4中如何配置打包使用相对路径

    这篇文章主要介绍了vuecli4中如何配置打包使用相对路径,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07

最新评论