Vuex父模块获取子模块修改后状态时数组删除操作变更未同步问题
问题根源
这个问题是Vue2响应式机制和Vuex状态序列化共同导致的:
- Vue2仅对数组的7种变异方法(
push/pop/shift/unshift/splice/sort/reverse)做了拦截封装,调用这些方法时会自动触发全链路的状态响应式更新,所以你调用addToArray用push修改数组时,父模块可以正常拿到最新值。 - 你在
deleteFromArray中直接给state.array赋值新数组的操作,不属于变异方法触发的更新,嵌套子模块的状态变更没有同步到根状态节点,导致父模块读取到的还是旧的数组引用。 - 直接把Vuex的响应式
state对象传给axios.post做序列化时,响应式对象的getter可能返回缓存的旧值,进一步放大了状态不一致的问题。
解决方案
第一步:修改子模块的删除mutation,用变异方法更新数组
把deleteFromArray的实现改为用splice删除元素,保证触发响应式更新:
"deleteFromArray"(state, payload) { const targetIndex = state.array.findIndex(item => item === payload) if (targetIndex > -1) { state.array.splice(targetIndex, 1) } }
第二步:提交请求前把响应式state转为普通对象
不要直接传响应式state给axios,先序列化剥离响应式代理后再提交,避免读取到缓存旧值:
"update"({commit, dispatch, state, rootState}) { // 转成普通JS对象再提交 const postData = JSON.parse(JSON.stringify(state)) axios.post(url, postData) }
如果你的项目里已经有深拷贝工具方法,也可以用深拷贝替代JSON.parse(JSON.stringify()),性能和兼容性更好。
内容的提问来源于stack exchange,提问作者Jesus Jimenez
相关产品推荐
相关产品推荐

