Vuex darkmode getter未正常更新,无法定位问题触发原因
问题核心原因
这个现象是由Vuex/Pinia的getter缓存机制和Vue响应式依赖收集规则共同导致的:
- Vue的getter仅会在它依赖的响应式状态发生变化时,才会重新计算,否则直接返回之前缓存的计算结果。
- 只有在getter执行过程中被访问到的响应式状态,才会被收集为该getter的依赖。
第一个版本getter能正常更新的原因
你的第一个getter逻辑中,哪怕进入了localStorage存在值的分支,仍然在if (state._darkmode)的判断语句中访问了响应式状态state._darkmode:
if (state._darkmode) { console.log("parsed", newDarkmode); } else { console.log("parsed", newDarkmode); }
因此state._darkmode会被收集为该getter的依赖,只要state._darkmode发生修改,getter就会重新执行、读取最新的localStorage值返回,看起来就是正常更新的。
第二个版本getter无法更新的原因
第二个版本的getter,只要localStorage中存在对应存储值,整个执行逻辑全程没有访问state._darkmode这个响应式状态:
darkmode: (state) => { if (localStorage.getItem(STORAGE_KEY_DARKMODE) === null) { return state._darkmode; } else { // 该分支下没有访问任何state里的响应式属性 const newDarkmode = JSON.parse( localStorage.getItem(STORAGE_KEY_DARKMODE) ); return newDarkmode; } },
而localStorage本身不是Vue的响应式数据,不会被纳入依赖收集。因此这个getter在首次执行走了localStorage分支后,就没有任何响应式依赖,后续不管state._darkmode怎么修改、localStorage的值怎么修改,getter都不会重新计算,只会一直返回首次缓存的结果,自然就无法正常更新。
修复方案
如果需要getter跟随state._darkmode更新同时读取localStorage的值,可以主动在getter中引用state._darkmode触发依赖收集即可,比如:
darkmode: (state) => { // 主动引用响应式状态,触发依赖收集 void state._darkmode; if (localStorage.getItem(STORAGE_KEY_DARKMODE) === null) { return state._darkmode; } return JSON.parse(localStorage.getItem(STORAGE_KEY_DARKMODE)); }
更合理的最佳实践是:修改暗黑模式状态时,同步更新state._darkmode和localStorage,不要让getter直接读取非响应式的localStorage,避免依赖不一致的问题。
内容的提问来源于stack exchange,提问作者Saab
相关产品推荐
相关产品推荐

