【vue3】优雅的解决reactive()响应式对象初始化重新赋值问题

45 篇文章 6 订阅
10 篇文章 0 订阅

代码里写了注意点,此处也先声明注意事项:

  • template 里必须绑定的是 ref() 数据源 !!

  • 重新初始化整个响应式对象时,用来数据操作的实际变量(例子里的info)也需要重新赋值!

  • 这是vue3没正式发布解决 ref()  `.value` 的语法糖的相对方案。正式敲定且发布后应该就可废弃我这方案了。

  • 为什么不用 Object.assign() 处理reactive()? 什么情况下用 Object.assign() 处理reactive()?

    • Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配(赋值)到目标对象。所以无法对例子里新增加的数据newKey清除掉!(这种问题常见于从后端接口获得的数据,有时候有{}值,有时候null)。此时不可用 Object.assign()

    • 严格定义对象的interface类型,确保数据完全在掌握范围内,可用 Object.assign()。

此方案解决的痛点:

  • const info = reactive() ,当info需要重新初始化时,需要用Object.assign(),但是Object.assign() 本质是合并对象并返回结果的新对象。用作初始化数据会导致潜在的问题,尤其是数据非前端可控的情况下(例如接口获得的数据)
    • 所以用ref声明,.value 赋值重新覆盖,才是最稳妥的初始化!(而且这种方法不用担心各种额外因素,降低心智负担~~)
  • 如果用ref.value存储响应式对象,操作起来每次要.value也会很麻烦。 解决这个问题的代码就是对应的 let info = xx  和 初始化的 info = xx 这两行代码! 
  • 数组类型的情况下:reactive([1,2]),重新赋值导致丢失响应,ref.value操作也不太方便,因此也可采用这方法。(或者说引用类型目前都可采用这方法)
<template lang="">
  <div>
    {{infoRef.newKey}}
    {{infoRef.bar}}
  </div>
</template>
<script lang='ts' setup>
import { ref,reactive } from 'vue';

const infoRef = ref<any>(source()) // template 里必须绑定的是 infoRef 不能是 info !!
let info = infoRef.value // Js里操作只操作 info 就可以不用 infoRef.value 了
function reset(){
  // 这样需要重置整个响应式对象就不需要 Object.assign和考虑深拷贝问题了
  infoRef.value = source()
  // 重新初始化整个响应式对象时,用来数据操作的实际变量也需要重新赋值!
  info = infoRef.value
}
function source(){
  return {
    foo:1,
    bar:2,
    obj:{a:1}
  }
}

// 测试
setTimeout(() => {
  info.bar *= 110
  info.newKey = 666
}, 3000);
setTimeout(() => {
  reset()
}, 6000);
setTimeout(() => {
  info.bar = 987654321
}, 8000);
</script>

QQ交流群:522976012  ,欢迎来玩。

聚焦vue3,但不限于vue,任何前端问题,究其本质,值得讨论,研究与学习。

  • 17
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值