vue3 中的 ref、reactive和v3响应式原理

一、ref函数

一般用来把简单数据类型处理响应式数据

声明的变量值用ref包裹,修改时通过 name.value去修改 

let name = ref('张三')

二、reactive函数

用来把对象类型的数据处理成响应式数据(数组也可以处理)

我们把reactive包裹的对称为源对象,返回的为代理对象(Proxy的实例对象,简称proxy对象

不管数据有多深,多复杂,reactive都可以进行处理,定义的响应式数据是深层次的

内部主要通过基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作,实现数据劫持

let job = reactive({
    type:'前端开发',
    salary:'30K'
})

  • 他们之间的区别

从数据角度

ref用来定义基本数据类型,而reactive用来定语对象(数组)类型

ref可可以定义对象(数组类型),但是内部还是借助reactive去实现响应式效果

原理上

ref通过Object.defineProperty中的get和set去实现时响应式(数据劫持)

而reactive是通过ES6中的Proxy实现数据劫持,并通过Reflect去操作源对象内部的数据

使用角度上

ref去操作数据需要用到 . value,读取不需要

reactive的操作和读取不需要 . value

三、vue3响应式原理

在vue2中我们主要通过Object.defineProperty中的get和set来实现 数据代理 和 数据劫持

而在vue3中主要是通过Proxy代理对象,

去拦截对象中任意属性的变化,包括属性的读写、属性的添加、和属性的删除等等,

通过relect反射对象,去对被代理对象进行操作

Proxy

Proxy接收两个参数,并返回一个代理对象

第一个参数是要代理的源对象,第二个参数是一个配置对象

在配置对象中有get、set、deleteProperty等配置项

读取属性的时候触发get

修改或者追加属性的时候触发set

删除属性的时候触发deleteProperty

  • get和deleteProperty接收两个参数

target:源对象

propName:发生变化的属性名

  • set接收三个参数

target:源对象

propName:发生变化的属性名

value:新值


Reflect 反射对象

  • Reflect.get( obj , ' a ')读取  接收两个参数

1.要读取的对象

2.要读取的属性

  • Reflect.set( obj , ' a ' , 111 ) 修改 接受三个参数

1.要修改的对象

2.要修改的属性

3.修改的值

  • Reflect.deleteProerty( obj , ' a ') 删除 接收两个参数

1.要删除的对象

2.要删除的属性

如果删除成功返回值为true,反之为false

 let person = {
      a: 'a',
      b: {
        c: 'c'
      }
    }
    //模拟vue3中实现响应式
    const p = new Proxy(person, {
      get (target, propName) {
        console.log(`有人读取了p身上的${propName}属性`);
        return Reflect.get(target,proName)
      },
      set (target, propName, value) {
        console.log(`有人修改了p身上的${propName}属性,我要去更新页面了`);
        Reflect.set(target,proName,value)
      },
      deleteProperty (target, propName) {
        console.log(`有人删除了p身上的${propName}属性,我要去更新页面了`);
        return Reflect.deleteProperty(target,proName)
      },
    })

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3,我们可以使用refreactive来定义响应数据。然而,有些情况下会导致响应丢失的问题。其reactive丢失响应的情况有两种。 第一种情况是直接赋值。当我们定义一个数据并使用reactive进行处理后,如果我们直接将一个新的值赋给这个数据,就会导致响应丢失。这是因为重新赋值后,这个数据的引用地址会发生变化,指向一个没有经过reactive处理的普通对象,而不是一个响应对象。所以,我们需要避免直接赋值给reactive定义的数据。 第二种情况是解构赋值。当我们对一个使用reactive处理的数据进行解构赋值时,同样会导致响应丢失。解构赋值会创建一个新的引用地址,指向一个没有经过reactive处理的普通对象。因此,我们在使用解构赋值时也需要注意避免丢失响应。 为了避免这些问题,我们可以使用toRefs函数将reactive对象转换为响应的引用对象,这样即使进行重新赋值或解构赋值,也能保持响应的特性。 总结起来,为了避免在Vue3丢失响应,我们需要注意避免直接赋值和解构赋值,可以使用toRefs函数来保持响应的特性。 #### 引用[.reference_title] - *1* *2* *3* [避大坑!Vue3reactive丢失响应的问题](https://blog.csdn.net/Yan9_9/article/details/128617371)[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^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值