思路
- app.use的语法怎么去注册的插件的?
- app.use(store); 会执行的是store.install方法,所以得在这里面关联上Vue
- app.config.globalProperties.store
- 怎么才能让全局的组件能用共享store?
- provide/inject使用注入的方式
- 数据怎么去响应式: vue的reactive钩子,reactive -> proxy的方式实现代理的
- 怎么去实现这些函数调用之间联动了?
- 发布订阅模式
下面就是我实现的代码,大佬看到了可以斧正
import { inject, reactive } from 'vue';
const storeKey = "store";
// 获取对象的属性和值
function foreachObjectProp(obj, cb) {
Object.keys(obj).forEach(item => {
cb(item, obj[item]);
})
}
export class Store {
// 配置项
constructor(options) {
// 响应式的数据
this.vm = reactive(options);
let getters = options.getters;
// getters
this.getters = {};
foreachObjectProp(getters, (key, value) => {
Object.defineProperty(this.getters, item, {
get: () => {
return value(this.state);
}
})
});
// actions mutations
let mutations = options.mutations;
this.mutations = {};
foreachObjectProp(mutations, (key, value) => {//发布订阅
this.mutations[key] = (data) => {
value(this.state, data);
};
})
let actions = options.actions;
this.actions = {};
foreachObjectProp(actions, (key, value) => {//发布订阅
this.actions[key] = (data) => {
value(this, data);// 这里用this 才能 { commit }
};
})
}
install(app, key) {//相对于vue2中的vue实例
console.log(app);
// 让每一个组件实例都有一个$store
app.config.globalProperties.$store = this;
// 给每个组件添加一个store实例
app.provide(key || storeKey, this);
}
// 获取响应式的数据
get state() {
return this.vm;
}
commit = (key, payload) => {
this.mutations[key](payload);
}
dispatch = (key, payload) => {
this.actions[key](payload);
}
}
// 创建一个store
export function createStore(options) {
return new Store(options);
}
// 在使用的组件中得到一个store
export function useStore(key = null) {
// 这样组件中就能获取到值
return inject(key || storeKey);
}