Vuex
Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必 须通过Mutation提交修改信息,Mutation同时提供了订阅者模式供外部插件调用获取State数据的 更新。 而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据。最后,根据State 的变化,渲染到视图上。
Vuex也是一个插件,需要提供install方法 供Vue使用,但是它的导出方式,跟router有一点区别
let Vue
class Store {
constructor(options) {
this.$options = options
this._mutations = options.mutations
this._actions = options.actions
this._wrappedGetters=options.getters
const computed={}
this.getters={}
//这里我们保存this指针
const store=this
Object.keys(this._wrappedGetters).forEach(key=>{
//获取用户定义的getter
const fn=store._wrappedGetters[key]
// 转换为computed可以使用的无参数形式,利用高阶函数实现
computed[key]=function(){
return fn(store.state)
}
//为getters定义只读属性
Object.defineProperty(store.getters,key,{
get(){
return store._vm[key]
}
})
})
//这里通过VUE代理将state中数据全部变成响应式数据,做一下数据的隐藏,防止修改数据
this._vm = new Vue({
data: {
$$state: options.state
},
computed
})
this.commit=this.commit.bind(this)
this.dispatch=this.dispatch.bind(this)
}
get state() {
return this._vm._data.$$state
}
set state(v) {
throw new Error('please use replaceState to reset state')
}
commit(type, payload) {
const entry = this._mutations[type]
if (!entry) {
throw new Error('unknow mutations')
}
entry(this.state, payload)
}
dispatch(type, payload) {
const entry = this._actions[type]
if (!entry) {
throw new Error('unknow actions')
}
// 这里因为actions内的方法参数具有store全部属性
entry(this, payload)
}
}
function install(_Vue) {
Vue = _Vue
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
}
},
})
}
export default {
Store,
install
}