Vue2中set用法及原理

文章详细讨论了Vue.js中Vue.$set的作用,它是用来确保在响应式对象中新增的属性保持响应式并触发视图更新。虽然有时不使用Vue.$set也能更新视图,但这并不总是可靠的。Vue.$set的原理涉及到Vue对数组和对象的劫持,对于数组,它拦截了某些方法以实现响应式;对于对象,它通过defineReactive方法添加getter和setter。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 前言:

前段时间给公司前端讲解$set使用场景,当场翻车了,很简单的问题,让我郁闷了一下午,各种查文档,终于知道了为啥对象新增一个属性,而这个属性在视图上更新了


咱们先聊下,vue.$set是什么?,怎么用?在什么场景下使用它?
概念:向响应式对象中添加一个property,并确保这个新的property同样是响应式的,且触发视图更新。

示例代码:

<template>
    <div>
         {{ userInfo }}
        <div>
          <button @click="handleAdd">新增属性</button>
          <button @click="handleEdit">修改属性</button>
        </div>

    </div>

</template>
export default{

    data(){
        userInfo:{
           name:"小甜甜"
        },  
    },
      methods: {
        handleAdd() {
          this.userInfo.age= "18";
          console.log(this.userInfo);
        },
        handleEdit() {
          this.userInfo.age= "28";
          console.log(this.userInfo);   
        }
    }

}

 问题描述:在响应式对象userInfo上新增age属性,视图并没有更新,但是在控制台可以打印出来

用法:

Vue.set(target,propertyName/index,value)
参数一: 目标对象或数组
参数二:对象属性或数组下标值
参数三:新增属性的内容
//在示例代码的基础上 使响应式对象userInfo新增的age属性也具有响应式
...
   handleAdd() {
      this.$set(this.userInfo, "age", 18);
    },  
...

但是,请看下面的代码,没有使用this.$set去新增age属性,age居然也更新了

...
    handleAdd(){
        //执行如下代码,视图里的age也被更新了
        this.userInfo.name="小宝贝";
        this.userInfo.age=18;
    }
...

原来:此时的   userInfo.age  并不是变成了响应式属性,而是  userInfo.name  更新了触发视图更新,所以userInfo.age在视图上也更新了!!!所以,终于破案了

总结:

  1. 由于vue2使用Object.defineProperty()对data,props,computed,watch,methods里的数据进行劫持,但它无法监听属性的新增和删除,所以需要使用setdelete
  2. set用于将响应式对象新增的属性变成响应式属性
  3. 注意有时候不使用set新增的属性在视图也更新了,可能是其它响应式属性更新触发了视图更新

 最后,我们谈谈Vue.set的原理是啥

  1. 当目标是数组的时候,借助vue内部拦截处理后数组的splice方法进行赋值。vue对数组的'push','pop','shift','unshift','splice','sort','reverse'方法进行拦截处理成响应式,调用这些方法,可以触发界面的更新
  2. 如果目标是对象,会先判断属性是否存在,对象是否是响应式,如果要对属性进行响应式处理,则是通过调用defineReactive方法。(defineReactive 方法就是 Vue 在初始化对象时,给对象属性采用 Object.defineProperty 动态添加 getter 和 setter 功能所调用的方法)
Vue.set方法的原理是将一个属性添加到Vue实例对象或其_data属性中,并将其转换为响应式属性。它的实现机制是通过改变属性的getter和setter,使得当属性的值发生变化时,能够通知相关的依赖进行更新。 具体来说,当使用Vue.set方法添加属性时,Vue会首先判断该属性是否已经存在于实例对象或_data属性中。如果存在,则直接返回该属性的值;如果不存在,则会通过Object.defineProperty方法将属性添加到实例对象或_data属性中,并将其设置为可监听的属性。这样一来,当该属性的值发生变化时,Vue会自动触发依赖追踪机制,通知相关的依赖进行更新。 需要注意的是,Vue.set方法只能用于添加响应式属性,即在数据被修改时能够触发视图的更新。如果需要添加非响应式的属性,可以直接使用普通的属性赋值方式进行添加。 综上所述,Vue.set方法的原理是通过改变属性的getter和setter,将属性添加到Vue实例对象或其_data属性中,并将其转换为响应式属性,以实现数据的双向绑定和视图的自动更新。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Vue-Vue.set() 的原理及使用](https://blog.csdn.net/qq_40792800/article/details/122427044)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值