首先在这个store文件夹里如图把vuex的引用从vue的插件改为本地文件形式
第二步在store文件夹下创建vue.js文件,也就是按照上图的"./vuex"的路径创建文件夹,我们的vuex实现就在这个文件夹里
在写源码之前先来了解一下vuex的使用,以便于思考源码的编写思路 其中store文件下的index文件需要配置参数state,mutations,getters和actions如下图所示
下图为在page文件中的使用,其中async按钮为actiosn的使用,actions是异步方法,加1减1按钮为mutations同步操作
async和加1减1的具体事件如下图
此代码运行结果如图
这里点击加1按钮,state和getters的值会立即加1,点击减1按钮state和getters的值会立即减1,而点击 async后会在1秒钟之后执行加1操作
了解了以上vuex的使用方法后直接上vuex模拟实现代码
let Vue;
class Store {
constructor(options) {
this.vm = new Vue({
data: {
state: options.state
}
})
//Store的vm把store里的state放在Vue的data中,就可以双向数据绑定了
let getters = options.getters || {}
this.getters = {}
Object.keys(getters).forEach(getterName => {
Object.defineProperty(this.getters, getterName, {
get: () => {
return getters[getterName](this.state);
}
})
})
let mutations = options.mutations || {}
this.mutations = {}
Object.keys(mutations).forEach(mutationName => {
this.mutations[mutationName] = payload => {
mutations[mutationName](this.state, payload)
}
})
let actions = options.actions || {}
this.actions = {}
Object.keys(actions).forEach(actionName => {
this.actions[actionName] = payload => {
actions[actionName](this, payload)
}
})
}
dispatch(method, payload) {
this.actions[method](payload)
}
commit = (method, payload) => {
//注意这里的commit要使用箭头函数,因为在调用dispatch的时候走到这个commit方法的时候this指向为undefined,改为箭头函数this指向为Vue
this.mutations[method](payload);
}
get state() {
return this.vm.state
}
}
const install = (v) => {
Vue = v;
Vue.mixin({ //mixin混入方法需要学习了解,这里混入的目的是给全局的Vue类加上$store
beforeCreate() {
if (this.$options && this.$options.store) {
//注意一定要熟练掌握this指向问题,这里this指向Vue
this.$store = this.$options.store;
} else {
this.$store = this.$parent && this.$parent.$store;
}
}
})
}
export default {
install, Store //将install方法和Store类导出
}
vuex中还有module这个属性,可以继续深入了解一下它的使用或者实现原理