1.使用
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
counter: 0
},
mutations: {
add(state) {
state.counter++
}
},
actions: {
add({ commit }) {
setTimeout(() => {
commit('add')
}, 1000);
}
},
modules: {
}
})
<template>
<div id="app">
<p @click="$store.commit('add')">counter: {{$store.state.counter}}</p>
<p @click="$store.dispatch('add')">async counter: {{$store.state.counter}}</p>
</div>
</template>
2.代码实现
let _Vue
class Store {
constructor(options) {
this._mutations = options.mutations
this._actions = options.actions
this._getters = options.getters
this.getters = {}
this._vm = new _Vue({
data() {
return {
$$state: options.state
}
},
})
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
}
get state() {
return this._vm._data.$$state
}
set state(val) {
console.error("不能直接设置state")
}
commit(type , playload){
const fn = this._mutations[type]
console.log(fn)
if (!fn) {
}else {
fn( this.state, playload)
}
}
dispatch(type , playload){
const fn = this._actions[type]
if (!fn) {
} else {
return fn(this,playload)
}
}
}
function install(Vue) {
_Vue = Vue
Vue.mixin({
beforeCreate(){
if(this.$options.store) {
Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install
}
3.getters 实现
Vue.use(Vuex)
export default new Vuex.Store({
state : {
counter : 2
},
getters : {
total(state) {
return "合计:" + state.counter
}
}
})
<template>
<div id="app">
<p >getters total: {{$store.getters.total}}</p>
</div>
</template>
constructor(options) {
this._getters = options.getters
this.getters = {}
let _this = this
for (const key in this._getters) {
const fn = this._getters[key];
Object.defineProperty(this.getters,key, {
get : () => {
return fn(_this.state)
}
})
}
}
4.getters 缓存实现
this._getters = options.getters
this.getters = {}
let _this = this
let computed = {}
for (const key in this._getters) {
const fn = this._getters[key]
computed[key] = function() {
return fn(_this.state)
}
Object.defineProperty(this.getters,key, {
get : () => {
return _this._vm[key]
}
})
}
this._vm = new _Vue({
data() {
return {
$$state: options.state
}
},
computed
})