vue3 响应式

1)失去响应式原因:

  1. Vue3中的响应性使用了Proxy对象来替代Vue2中的Object.defineProperty。
  2. 而Proxy对象只能对整个对象进行拦截,而无法对对象的属性进行拦截。
    因此,在使用解构赋值时,解构的对象会被转化为普通的JavaScript对象,而丢失了Vue3的响应性。

  3. 解构赋值实际上是创建一个新的对象,这个对象与原始对象不再具有相同的引用且没有经过响应性劫持 ,不再与Vue3的响应式系统关联
    原始类型的赋值相当于按值传递, 引用类型的值就相当于按引用传递

    //  const a=b:1}   假设a是个响应式对象
    //  const c=a.b     此时就是一个值跟当前的a 已经不沾边了
    // 你直接访问c就相当于直接访问这个值 也就绕过了 a 对象的get ,也就失去响应式


    //  const a=b:{c:3}}假设a是个响应式对象 
    // const c=a.b    当你访问a.b的时候就已经重新初始化响应式了,此时的c就已经是个代理的对象
     // 你直接访问c就相当于访问一个响应式对象,所以并不会失去响应式
    因为a.b 是引用类型,源码中判断如果是个object 那么就重新包装为响应式

  4. 解决方案:

    可以使用toRefs函数来将解构赋值的结果转换为响应式的。toRefs函数可以接收一个响应式对象,并将其转换为具有响应性的Ref对象。这样,解构赋值的结果对象就能够保持响应性。

    reactive函数将解构赋值的结果对象转化为响应式对象。reactive函数可以接收一个普通的JavaScript对象并返回一个具有响应性的Proxy对象,从而保持对象的响应性。

总结起来,Vue3中的解构赋值会丢失响应性是因为解构赋值创建了一个新的对象,该对象不再具有Vue3的响应性

 

 

2)reactive丢失响应式的情况1(直接赋值)

场景:
1.你定义了一个数据:
let data=reactive({
  name:"",
 age:""
})
2.然后你请求了接口,赋值给data
let res=await getUserApi();  //请求接口
data=res.data; //将返回的结果赋值给data
 
 

大错特错!!!

 

reactive丢失响应式的情况2(解构赋值)

场景:
1.你定义了一个数据:
let data=reactive({
  name:"",
  age:""
})
2.然后你解构了
let {name}=data; //解构赋值
 

大错特错!!!

 

了解响应式

1.ref 定义数据(包括对象)时,都会变成 RefImpl(Ref 引用对象) 类的实例,无论是修改还是重新赋值都会调用 setter,都会经过 reactive 方法处理为响应式对象。
2.但是 reactive 定义数据(必须是对象),是直接调用 reactive 方法处理成响应式对象。如果重新赋值,就会丢失原来响应式对象的引用地址,变成一个新的引用地址,

这个新的引用地址指向的对象是没有经过 reactive 方法处理的,所以是一个普通对象,而不是响应式对象。解构同理。

 

避坑办法:

避开直接赋值和结构,reactive直接包裹一个对象。

let data=reactive({
    userData:{}        //里面定义一个对象,这样赋值就不会丢失响应式了。
})
  
//获取接口数据
let res=await getUserApi();  //请求接口
data.userData=res.data;      //将返回的结果赋值给data

简单数据类型使用ref()来进行定义。

 

 

 

这个很牛
https://blog.csdn.net/song854601134/article/details/127284112

posted @ 2024-05-21 15:53  青橙娃娃  阅读(56)  评论(0编辑  收藏  举报