今天用vue3+vite+store想要完成一个单处变更至全局动态变化的问题,但是遇到了一个很奇怪的现象,我大致知道可能是内置变量机制的问题,但是请教大神告知深层次的原因
版本如下
功能描述大概就是,左侧树节点点击后会触发修改
//节点点击触发事件
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)
};
不进行深拷贝控制台打印如下
进行深拷贝后页面渲染及控制台打印如下
不是说深拷贝是该方法必须,而是一个现象提取;更直观的原因是我不能对store.getters.getChoosedDeptPost获得的数组进行存储域重定向,即不能重新赋值代码中的“savedposts”,即只能变更原数组,类似于filter过滤等重新赋值操作都不能。也不是说非要用重新复制的方法去做,只是想知道不能的底层逻辑是什么,请各位大佬萌新小可爱程序员程序猿们帮忙解答,靴靴~
有点没看明白,不过大概猜测是和你给对象的赋值操作相关。因为当你将一个新的对象赋值给
savedposts
这个变量,那么变量savedposts
将指向新对象的内存地址,而不是原来的内存地址了。即你说的只能变更原数组,类似于filter过滤等重新赋值操作都不能。具体可以参考我在这个问答中的一些举例说明 👉 为什么new Map也被垃圾回收了?
可能会帮助你理解引用关系方面的一些疑惑。
所以一般来说我们并不会在外部直接操作
Vuex
的state
值,通过commit
去提交Mutations
中的修改操作给Vuex
来处理。以及获取
state
的时候会通过mapState
或者mapGetters
来获取,而不是直接store.state.xxx
这样了获取,以避免直接修改state
。另外,你是使用
JSON.parse(JSON.stringify(savedposts))
这样取巧的方式来实现的深拷贝。“拷贝”出来的结果会丢失很多的信息,比如说:这块内容可能你自己做一下手写深拷贝函数会理解的更好一些。