1 the use of
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>
Copy the code
2. Code implementation
let _Vue
class Store {
constructor(options) {
this._mutations = options.mutations
this._actions = options.actions
this._getters = options.getters
this.getters = {}
// Use vUE instances to implement responsiveness
this._vm = new _Vue({
data() {
return {
$$state: options.state // Add $sign to data that cannot be externally used directly with _vm.$$state}}})this.commit = this.commit.bind(this) // Bind must be assigned, otherwise the this binding is invalid
this.dispatch = this.dispatch.bind(this)}// Use es6 get set method to protect data effectively
get state() {$$state = this._vm._data.$$state = this._vm
return this._vm._data.$$state
}
set state(val) {
console.error("State cannot be set directly")}commit(type , playload){
const fn = this._mutations[type]
console.log(fn)
if(! fn) {// throw Error('unknow mutation')
}else {
fn( this.state, playload)
}
}
dispatch(type , playload){
const fn = this._actions[type]
if(! fn) {// throw Error('unknow action')
} else {
return fn(this,playload)
}
}
}
function install(Vue) {
_Vue = Vue // Record the global instance
Vue.mixin({
beforeCreate(){
if(this.$options.store) {
Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install
}
Copy the code
3. The getters
/ / use
Vue.use(Vuex)
export default new Vuex.Store({
state : {
counter : 2
},
getters : {
total(state) {
return "Together." + 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)
}
})
}
}
Copy the code
4. Getters cache implementation
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]
}
})
}
// Use vUE instances to implement responsiveness
this._vm = new _Vue({
data() {
return {
$$state: options.state // Add $sign to data that cannot be externally used directly with _vm.$$state
}
},
computed // Implement caching using vUE computed
})
Copy the code