当前位置: 首页 > 知识库问答 >
问题:

前端 - vue3.0+vite+store 变量赋值问题?

俞新翰
2024-05-16

今天用vue3+vite+store想要完成一个单处变更至全局动态变化的问题,但是遇到了一个很奇怪的现象,我大致知道可能是内置变量机制的问题,但是请教大神告知深层次的原因

版本如下
image.png

功能描述大概就是,左侧树节点点击后会触发修改

//节点点击触发事件const toggleNodeChoosed=(clicked)=>{  clicked.choosed=!clicked.choosed;  let savedposts = store.getters.getChoosedDeptPost;//从store获取选数据  if(!savedposts){    savedposts=[]  }  // 如果我对该值进行深拷贝,则功能无效,注释掉本行之后功能正常  // savedposts=JSON.parse(JSON.stringify(savedposts));  console.log("11111111",savedposts)  if(!clicked.choosed){    while(savedposts.some((item)=>item.postcode===clicked.code)){      savedposts.forEach((item,index)=>{        if(item.postcode==clicked.code){          savedposts.splice(index,1)        }      })    }  }else if(clicked.choosed){    let {code,name}=clicked;     savedposts.push({code,name});  }  store.commit("setChoosedDeptPost",savedposts)};

image.png

不进行深拷贝控制台打印如下

image.png

进行深拷贝后页面渲染及控制台打印如下

image.png

不是说深拷贝是该方法必须,而是一个现象提取;更直观的原因是我不能对store.getters.getChoosedDeptPost获得的数组进行存储域重定向,即不能重新赋值代码中的“savedposts”,即只能变更原数组,类似于filter过滤等重新赋值操作都不能。也不是说非要用重新复制的方法去做,只是想知道不能的底层逻辑是什么,请各位大佬萌新小可爱程序员程序猿们帮忙解答,靴靴~

共有1个答案

何安宜
2024-05-16

有点没看明白,不过大概猜测是有哪位和你给对象的操作相关。
因为当你将一个新的对象赋值给 savedposts 这个变量,那么变量 savedposts 将指向新对象的内存地址,而不是原来的内存地址了。即你说的只能变更原数组,类似于filter过滤等重新赋值操作都不能。

具体可以参考我在这个问答中的一些举例说明 �� 为什么new Map也被垃圾回收了?
可能会帮助你理解引用关系方面的一些疑惑。


另外,你是使用 JSON.parse(JSON.stringify(savedposts)) 这样取巧的方式来实现的深拷贝。“拷贝”出来的结果会丢失很多的信息,比如说:

  1. 无法复制函数:如果对象中包含函数,那么该函数将不会被复制。
  2. 无法复制循环引用的对象:如果对象中存在循环引用,例如对象 a 的属性 b 指向 a,那么这种方式将会抛出错误。
  3. 无法复制特殊的对象:像 DateRegExpMapSet 等特殊对象在序列化后,不能恢复为原来的对象。
  4. 无法复制 undefined:如果对象中的某个属性值为 undefined,那么这个属性将不会被复制。

这块内容可能你自己做一下手写深拷贝函数会理解的更好一些。

 类似资料:
  • 版本 vite ^5.2.8 vue ^3.4.21 源码: 编译后 错误 问题 在开发环境可以正常赋值 如何正确赋值 如何让vite编译时保留class的源码

  • = 赋值操作符(它的左右两边不能有空白符) 不要搞混了 = 和 -eq,-eq 是比赋值操作更高级的测试。注意:等于号(=)根据环境的不同它可能是赋值操作符也可能是一个测试操作符。 例子 4-2. 简单的变量赋值 1 #!/bin/bash 2 # 裸变量 3 4 echo 5 6 # 什么时候变量是“裸”的?比如说,变量名前面没有$? 7 #当变量被赋值

  • 我的代码是这样的: 但最后一句话: 总是停止编译说我需要给新变量分配一个返回值?在if语句之前,已经为k分配了一个值。当我把随机k语句放在if语句中时,它似乎是有效的,但这使得它毫无价值,不是吗?编辑器本身没有错误,但是当我编译时,它给了我这个: 线程“main”java中出现异常。lang.IndexOutOfBoundsException:索引:41,大小:36。util。ArrayList。

  • 原文: http://exploringjs.com/impatient-js/ch_variables-assignment.html 下面这些是 JavaScript 声明变量的主要方式: let用来声明可变变量。 const用来声明常量(不可变变量)。 在ES6之前,还有var。但它有些怪癖,所以最好在现代JavaScript程序中避免使用它。你可以在“Speaking JavaScript

  • 本文向大家介绍详解PHP变量传值赋值和引用赋值变量销毁,包括了详解PHP变量传值赋值和引用赋值变量销毁的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了PHP变量传值赋值和引用赋值变量销毁的具体代码,供大家参考,具体内容如下 php中,上面的代码,变量是怎么存放的呢? 上面的代码变动下,将变量b赋值给变量a,会发生什么? 问题来了,$a = $b,那么是将变量a的指针指向了变量b指针所