找回密码
 立即注册
首页 业界区 业界 vue3小坑之-为什么把ref定义的数组赋值给数组对象后取值 ...

vue3小坑之-为什么把ref定义的数组赋值给数组对象后取值为空数组?

倘伟 7 天前
天呢,居然两年没有上博客园看过了,呜呜呜,日渐废柴
这次总结一个码代码的时候遇到的问题,为什么把数据赋值给数组对象的某个字段,打印出来的是个空数组?
错误写法一:
  1. // 动态获取list值,前端可以增删改查
  2. const list = ref([
  3.   // 也许有数据也许没数据
  4. ])
  5. // 将值赋值给数组对象的某元素arr
  6. const listArr = ref([
  7.   { type: 'fuzhi', arr: list.value },
  8. ])
  9. // 不管list是否有值,打印出来的都是空数组,数据失去响应了
  10. console.log(listArr[0].arr)
复制代码
怎么不行了呢?此时还不知道原因,那我换个写法试试
错误写法二:
  1. const list = ref([])
  2. // 赋值整个ref响应式的数据
  3. const listArr = ref([
  4.   { type: 'fuzhi', arr: list},
  5. ])
  6. // 打印出来的还是空数组
  7. console.log(listArr[0].arr.value)
复制代码
恩?结果还是不行?我确定这样是引用的地址呀?在我使用了AI大法和百度大法之后,终于找到了原因如下:
写法一相当于:
  1. const snapshot = list.value // 获取当前快照
  2. const listArr= ref([{ arr: snapshot }]) // 存储静态拷贝
复制代码
ref的.value会解包当前的对象值,深拷贝了一份数据.理解成只要.value一次,就生成了当前数据的一份快照.
没错,不管什么时候,只要定义一个变量接受xxx.value,当前xxx.value是什么值,那它将永远都是什么值,后面xxx.value的所有变动都与这个变量没有半毛钱关系.所以,到这里,响应式就被切断了!!!
案例中,使用ref创建了list为空数组,则初始化的值是空数组.紧接着写代码给listArr赋值,直接取了此时的list.value值,也就是空数组(如果初始化的时候是其他值,那么这里赋值的就是其他值)
有点绕,再多看几遍,打一打代码就懂了~
针对写法二:
我菜鸟的认为,这样一定能行,因为我是把整个响应式变量都搬过来了,按道理来说应该是可以实时获取最新的数据呀.不是说引用了地址就能时实追踪么?
答案来了~
Vue3不会自动解包嵌套在对象/数组中的ref,即使通过.value[0].arr.value完整路径访问,响应式更新也无法穿透多层结构
也就是说,Vue只能追踪到listArr.value的变化。此时就算是list更新了,也没办法感知到,这里响应式中断了!
 
那么,要怎么写才正确呢?下面是三种方法供参考,实测有效
  1. const list = ref([])
  2. // 方法一:使用toRef,让arr转为响应式数据
  3. const listArr = ref([
  4.   { type: 'fuzhi', arr: toRef(list, 'value') },
  5. ])
  6. console.log(listArr.value[0].arr.value)
  7. // 方法二:使用reactive,reactive可以解决嵌套ref响应式失效的问题
  8. const listArr = reactive([
  9.   { type: 'fuzhi', arr: list },
  10. ])
  11. console.log(listArr[0].arr)
  12. // 方法三:使用computed
  13. const listArr= computed(() => [{ type: 'fuzhi', arr: list }])
  14. console.log(listArr.value[0].arr.value)
复制代码
小伙伴们可以自己找个适合自己的方法,结束结束~

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册