一、概念
(1)Vuex 是一个状态和数据管理的框架,负责管理项目中多个组件和多个页面共享的数据。
(2)在开发项目的时候,我们就会把数据分成两个部分,一种数据是在某个组件内部使用,我们使用 ref 或者 reactive 定义即可,另外一种数据需要跨页面共享,就需要使用Vuex 来进行管理
(3)Vuex使用 state 定义数据,使用mutation定义修改数据的逻辑,并且在组件中使用 commit 去调用 mutations。在此基础之上,还可以用 getters 去实现 Vuex 世界的计算属性,使用 action 来去定义异步任务,并且在内部调用 mutation 去同步数据。
(3) Vuex 在整体上的逻辑如下图所示,从宏观来说,Vue 的组件负责渲染页面,组件中用到跨页面的数据,就是用 state 来存储,但是 Vue 不能直接修改 state,而是要通过 actions/mutations 去做数据的修改。
二、手写迷你Vuex
(1)在 Vue 中有provide/inject 这两个函数专门用来做数据共享,provide 注册了数据后,所有的子组件都可以通过 inject 获取数据。
(2)使用一个 Store 类来管理数据,类的内部使用 _state 存储数据,使用mutations 来存储数据修改的函数,注意这里的 state 已经使用 reactive 包裹成响应式数据了。
(3)暴露了 createStore 去创建 Store 的实例。
(4)暴露了 useStore 去获取 Store 的实例。
(5)使用 store ,在项目入口文件 src/main.js 中使用 app.use(store) 注册。为了让 useStore 能正常工作,下面的代码中,需要给 store 新增一个 install 方法,这个方法会在 app.use 函数内部执行。通过 app.provide 函数注册 store 给全局的组件使用。
(6)Store 类内部变量 _state 存储响应式数据,读取 state 的时候直接获取响应式数据 _state.data,并且提供了 commit 函数去执行用户配置好的 mutations。
import { inject, reactive } from "vue";
const STORE_KEY = "__store__";
function useStore() {
return inject(STORE_KEY);
}
function createStore(options) {
return new Store(options);
}
class Store {
constructor(options) {
this._state = reactive({
data: options.state(),
});
this._mutations = options.mutations;
}
// main.js入口处app.use(store)的时候,会执行这个函数
install(app) {
app.provide(STORE_KEY, this);
}
get state() {
return this._state.data;
}
commit = (type, payload) => {
const entry = this._mutations[type];
entry && entry(this.state, payload);
};
}
export { createStore, useStore };