import Vue from 'vue';
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
counter: 1
},
mutations: {
add(state) {
return state.counter++
}
},
actions: {
addSync({ commit }, proload) {
setTimeout(() => {
commit('add', proload)
}, 1000)
}
},
getters: {
doubleCounter(state) {
return state.counter * 2
},
mutilCounter(state) {
return state.counter * state.counter
}
},
modules: {
}
})
1.实现Store类中的响应式state,commit,dispath,响应式getters
2.实现Store的安装,定义install方法,使用vue.use()方式安装
3.不考虑实现modules模板
1. Store
保存选项:mutations, _actions,getters
响应式状态:new Vue({data: {$$state: options.state}})
Get state()/set state()
Commit(): entry => entry(this.state)
dispatch(): entry => entry(this)
2. Install
Vue.prototype.$store
const install = (_Vue) => {
Vue = _Vue
Vue.mixin({
created() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
}
},
})
}
class Store {
constructor(options) {
const state = options.state
this.mutations = options.mutations
this.actions = options.actions
this.getters = options.getters
}
}
将state定义 为 vue响应式 数据 ,可以使用new Vue()实例定义响应式数据,或者利用 Vue.util.defineReactive(this, “state”, state)定义响应式state.
this._vm = new Vue({
data() {
return {
$$state: state
}
},
})
利用es6中的get与set方法获取响应式state
get state() {
return this._vm._data.$$state
}
set state(v) {
console.log('please use replaceState to reset state!');
}
实现commit和dispatch方法
//commit触发muations
commit = (type, proload) => {
const fun = this.mutations[type]
// console.log(type, fun, 'fun');
if (fun) {
fun(this.state, proload)
} else {
console.log('commit方法未定义')
}
}
//commit触发actions
dispatch = (type, proload) => {
const fun = this.actions[type]
if (fun) {
fun(this, proload)
} else {
console.log('actions方法未定义')
}
}
注意:最好是利用箭头函数,否则会存在this指向问题
可以定义普通函数,利用bind绑定函数this的上下文
实现响应式getters
利用上面创建的new Vue({})实例,将getters方法映射成vue computed属性的方法,挂载computed计算属性
Object.keys(this.getters).forEach(v => {
computed[v] = this.getters[v]
const vm = this._vm
Object.defineProperty(this.getters, v, {
get() {
return vm.$options.computed[v](vm._data.$$state)
}
})
})
导出Store和install
export default { install, Store }
5.kVuex整体代码
/* eslint-disable no-unused-vars */
let Vue
class Store {
constructor(options) {
const state = options.state
this.mutations = options.mutations
this.actions = options.actions
this.getters = options.getters
const computed = {}
//state响应式的
// Vue.util.defineReactive(this, "state", state)
//初始化Vue实例,监测state为响应式数据
this._vm = new Vue({
data() {
return {
$$state: state
}
},
computed
})
Object.keys(this.getters).forEach(v => {
computed[v] = this.getters[v]
const vm = this._vm
Object.defineProperty(this.getters, v, {
get() {
return vm.$options.computed[v](vm._data.$$state)
}
})
})
}
get state() {
return this._vm._data.$$state
}
set state(v) {
console.log('please use replaceState to reset state!');
}
//commit触发muations
commit = (type, proload) => {
const fun = this.mutations[type]
// console.log(type, fun, 'fun');
if (fun) {
fun(this.state, proload)
} else {
console.log('commit方法未定义')
}
}
//commit触发actions
dispatch = (type, proload) => {
const fun = this.actions[type]
if (fun) {
fun(this, proload)
} else {
console.log('actions方法未定义')
}
}
}
const install = (_Vue) => {
Vue = _Vue
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
// console.log(this.$options.store, 'store');
}
},
})
}
export default { install, Store }