前言
本文主要参照学习视频实现一个简单版本的vuex
代码地址
https://codesandbox.io/s/vue-code-study-mpewl
实现内容
- store
- state
- mutations
- actions
- getters
- 响应式
代码实现
let Vue;
class Store {
constructor(options) {
// 同样对vue强依赖 使用vue实现响应数据的更新
this.state = new Vue({
data: options.state
});
this.mutations = options.mutations;
this.actions = options.actions;
options.getters && this.handleGetters(options.getters);
}
//为什么没有定义到构造器内部?因为每个实例可以公用这些方法
// 为mutations actions getters为每个实例化单独享有的
// 声明为箭头函数,why?为了直接可以使用this.mutations,this.state
commit = (type, arg) => {
this.mutations[type](this.state, arg);
};
dispatch(type, arg) {
this.actions[type](
{
commit: this.commit,
state: this.state
},
arg
);
}
// getters为参数 而this.getters是实例化的
handleGetters(getters) {
this.getters = {};
// 遍历getters所有key
Object.keys(getters).forEach(key => {
// 为this.getters定义若干属性,这些属性是只读的
// $store.getters.score
Object.defineProperty(this.getters, key, {
get: () => {
return getters[key](this.state);
}
});
});
}
}
function install(_Vue) {
Vue = _Vue;
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store;
}
}
});
}
export default { Store, install };
要点分析
vue使用外来依赖
因为插件本身就使用了传入的vue,因此尽量不要内部定义vue,直接从从参数获取。
mixin
是否需要混入,混入本身很好用,但使用混入的最大前提是需要拿到组件的实例,如果你不希望或者不用拿到,那么直接定义到Vue的原型上即可。
getter为什么是只读的
通过Object.defineProperty实现定义一个get函数,让其变成只读的
箭头函数
当你需要使用外部环境,并且在组件实例的使用中不受影响的话,你就因该考虑箭头函数。