如何从异步的Promise外部获取then内的res,解决方法:最好用ref包数组(此处也尝试多种方式用reactive正确包裹数组)

如何从异步的Promise外部获取then内的res,解决方法:最好用ref包数组(此处也尝试多种方式用reactive正确包裹数组)

问题描述:

  1. 由于在Vue2的data中的数据是响应式的,但Vue3在使用组合api的setup内的数据没有响应式,于是Vue3 提供实现响应式数据的方法ref和reactive 。

  2. 当axios请求数据时,使用了Promise,由于只能从then中获取数据。此时,就需要解决:

     - 外部如何获取数据
     - ref使用
     - 若使用reacitive,如何正确用reacitive包裹数组以至于不失去响应式
    

认识ref

  1. 是 Vue3 中提供的实现响应式数据的方法。
  2. 操作普通数据类型,如数值、字符串、布尔值、数组最好不要用在对象

认识reactive

  1. reactive 是 Vue3 中提供的实现响应式数据的方法。
  2. 操作复杂数据类型,如对象。操作数组时有陷阱,下面有介绍规范。
  3. 在 Vue2 中响应式数据是通过 defineProperty 来实现的
  4. 在 Vue3 中响应式数据是通过 ES6 的 Proxy来实现的。

遇到的问题

  • 当axios使用了Promise请求数据时是异步的,只能从then中获取数据,那么如何从then的外部获取数据
  • reactive直接接收数组会有陷阱,只能用push才不会失去响应性,如何使数据仍然是响应式数据,在模板中渲染。

解决方法

  1. 错误方法:使reactive直接接收一个空数组 []
   //reactive直接接收数组会有陷阱,只能用push才不会失去响应性
    const result = reactive([]); 

   getAllProduct().then((res)=>{
     console.log('then内部的res',res.list);
     result = res.list
   })
   console.log('then外部的result', result);
   return {result}

显示结果:
then内部已经获取到数据了,但是外部的reactive的实例无法被更新,且模板中无法渲染出数据列表。

在这里插入图片描述

  1. 正确方式1:reactive里面传入对象(包含数组)
    const result = reactive({
      list: [],
    }); 

    getAllProduct().then((res) => {
      console.log("then内部的res", res.list);
      result.list = res.list;
    });
    console.log("then外部的result", result);
    return { result };

执行结果:
模板中数据正确渲染,保持了响应式。console中正确打印出查询的数据,then的内部和外部都有正确的结果

模板中渲染出
在这里插入图片描述

  1. 正确方式2:解决传入空数组 [] 失去响应式问题,遍历获取的数据一个个使用push进创建的数组
	const result = reactive([]);

    getAllProduct().then((res) => {
      console.log("then内部的res", res.list);
      res.list.forEach((e) => {
        result.push(e);
      });
    });
    console.log("then外部的result", result);
    return { result };

结果是正确的,模板中可渲染,且then外部正确接收到数据。

  1. 正确方式3:使用 ref 创建
	const result = ref([]);

    getAllProduct().then((res) => {
      console.log("then内部的res", res.list);
      result.value = res.list;
    });
    console.log("then外部的result", result);
    return { result };

结果显示正确,模板中可渲染,且then外部正确接收到数据。

在这里插入图片描述

  1. 正确方式4:解决reactive传入空数组 [] 问题,使用扩展符… ,类似于遍历并push的简写
	const result = reactive([]);

    getAllProduct().then((res) => {
      console.log("then内部的res", res.list);
      result.push(...res.list)
    });
    console.log("then外部的result", result);
    return { result };

结果显示正确,模板中可渲染,且then外部正确接收到数据。

总结

  • 正确使用 reacitive 包裹数组方法
    • 传入对象类型,因为reactive本来就接收对象类型数据 const result = reactive({list: []});
    • 硬要直接传入空数组 [] ,const result = reactive([]);
      • 使用foreach遍历数组,push进目标数组
      • 使用扩展符…,类似于上面的方法
  • 还可以使用 ref 创建响应式数组,ref 本身是接收普通类型数据的,记得ref数据要.value
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值