酷狗直播官方版
87.31MB · 2025-11-15
Vuex 是专门为 Vue.js 应用提供状态管理模式的一个库,也是 Vue.js 官方推荐的状态管理方案,它将所有数据集中存储到一个全局 store 对象中,并制定了一定的规则,保证状态以预期的方式发生变化。
它的核心概念有:
在构建中大型单页应用时,各组件和模块的状态流转逻辑会相当复杂,这时候就可以使用 Vuex 进行全局状态管理,并且里面用严格的 mutation 保证了状态的预期流转,使得项目的数据流变得清晰,提高了项目可维护性。
数据丢失原因:Vuex 中的状态 state 是存储在内存中的,刷新页面会导致内存清空,所以数据丢失。
解决方案:
将 Vuex 的数据在合适时机(比如监听 window 的beforeunload 事件)保存到浏览器的本地存储(localStorage 或 sessionStorage),也可以直接采用 vuex-persistedstate 持久化插件(默认会存储到 localStorage 中,可通过配置修改)进行本地存储。
应用初始化加载时,获取存储中的状态进行替换。Vuex 给我们提供了一个 replaceState(state: Object) API,可以很方便进行状态替换。
在状态替换后,还需要检查 Vuex 中的数据是否存在,如果不存在则可以在 action 中发送接口请求拿到数据,通过提交 mutation 修改状态把数据存储到 store 中。
状态变化后将状态同步到浏览器存储中,保证本地存储中状态的实时性。
dispatch 时会将 action 包装成 promise,而 mutation 则没进行包装。strict: true 后,任何非 mutation 函数修改的状态,将会抛出错误。其核心思路如下:
this._committing 表示程序是否处于 commit 执行过程。下一次 Tick 中调用) 监听 store 中的 state 状态(深度监听)。commit 执行过程中,state 发生了变化,在开发环境会报错。class Store {
commit(_type, _payload, _options) {
this._withCommit(() => {
// commit 中的处理
entry.forEach(function commitIterator(handler) {
handler(payload);
});
});
}
_withCommit(fn) {
const committing = this._committing;
this._committing = true;
fn(); // 如果函数内部有异步修改状态逻辑,则下面的 watch 时会报错
this._committing = committing;
}
}
function enableStrictMode(store) {
watch(
() => store._state.data,
() => {
if (__DEV__) { // 开发环境报错
assert(
store._committing,
`do not mutate vuex store state outside mutation handlers.`
);
}
},
{ deep: true, flush: "sync" } // 定义同步的 watcher 进行同步监控
);
}
用官方的话来说就是,“使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。”
所以我们在开发复杂应用时,可以按照业务逻辑将应用状态进行 modules 拆分,比如:
这样在开发应用和维护状态时更加精细和清晰,可维护性更强。
Pinia 是以 Vuex 5 为原型,由 Vue.js 官方团队开发的新一代 Vue 官方推荐的状态管理方案。
它对比 Vuex 有以下区别:
Vue3 + Pinia;Vuex -> Pinia,是一次,无疑和 Vue2 -> Vue3 一样,是一次大的破坏性升级,工作量还是相当大的。以上是整理的 Vuex 的高频面试题,如有错误或者可以优化的地方欢迎评论区指正,后续还会更新 Vue-router 相关面试题。