vue3 ref reactive响应式数据 赋值的问题

vue3 ref reactive响应式数据 赋值的问题

doing 遇见就记录,最后更新时间23.8.30

场景1:将响应式数据赋值请求后的数据

错误示范:直接赋值

以数组为例,对象也是一样的操作。

let list = ref([])
//let list = reactive([])
async function getList() {
    
    
    list = await httpGetList();  // 直接赋值错误
}
// 请求
function httpGetList() {
    
    
      return new Promise((resolve, reject) => {
    
    
        setTimeout(() => {
    
    
          resolve([1, 2, 3, 4, 5])
        }, 500)
      })
}

ref定义的属性等价于reactive({value:xxx}),所以reactive、ref 直接重新赋值丢失响应是因为引用地址变了

正确写法

  • 方法1:ref.value,代码中更为清晰地表明响应式数据
list.value = await httpGetList();
  • 方法2:包一层reactive,可以将一个模块的变量包在一个reactive里面,当作vue2的data
let data = reactive({
    
    
	list:[]
})
async function getList() {
    
    
    data.list = await httpGetList();
}

ref定义的属性等价于reactive({value:xxx}),方法2其实就是参考了该方式。

  • 方法3:更推荐方法1和方法2
let list = reactive([])
    
async function getList2() {
    
    
    let resp = await httpGetList()
    list.push(...resp)
}

场景2:响应式数据解构之后失去响应式

原因分析

reactive内部的实现是创建一个代理对象Proxy,以及进行了一系列处理。reactive失去效应是不在于Vue而在于Proxy对象本身。
解构相当于将该变量重新赋给(基础数据传值,引用类型传地址)了一个新变量,所以解构之后是一个基础数据则会响应式丢失。如果解构之后是一个引用类型,相当于操作的地址还是被Proxy监管,所以响应式不会丢失。

案例
比如解构之后是基础类型的数据,那么解构相当于copy了一个值。访问时直接访问的这个copy值,跳过了代理,所以不会触发getset
在这里插入图片描述

解决办法 toRefs/toRef方法创建ref引用对象

解构赋值主要还是赋值!对于基本数据类型,函数传递或者对象解构时,会丢失原始数据的引用。

  • toRef(响应式对象,该对象的属性)创建一个ref对象该ref对象value值指向参数对象中的某个属性
    ref对象的value值改变,参数对象中的该属性也会改变,反之也会改变,因为指向同一个地址!本质是引用,与原始数据有关联
    在这里插入图片描述
  • toRefs(obj):返回一个和参数一致的普通对象,只不过属性的值都变成了ref对象,相当于每个属性都执行了一次toRef

猜你喜欢

转载自blog.csdn.net/qq_41370833/article/details/132565060