myVuex.js:
import Vue from 'vue'
class Store {
constructor(options){
//实例一个vue,把数据存储在data里把数据做成响应式
this.vm = new Vue({
data(){
return {
state:options.state
}
}
})
//mutations方法
let mutations = options.mutations || {}
this.mutations = {}
for(let key in mutations){
this.mutations[key] = (arg) => {
mutations[key](this.state,arg)
}
}
//action方法
let actions = options.actions || {}
this.actions = {}
for(let key in actions){
this.actions[key] = (arg) => {
actions[key](this,arg)
}
}
//getters方法
let getters = options.getters || {}
this.getters = {}
for(let key in getters){
Object.defineProperty(this.getters,key,{
get:()=>getters[key](this.state)
})
}
}
//获取state响应式值
get state(){
return this.vm.state
}
//调用mutation
commit = (method,arg) => {
this.mutations[method](arg)
}
//调用action
dispatch = (method,arg) => {
this.actions[method](arg)
}
}
let install = (vue) => {
//把mixin的内容混合到Vue
vue.mixin({
//在beforeCreate把$options.store挂在组件$store,让每个组件都能通过this.$store调用
beforeCreate(){
this.$store = null
if (this.$options && this.$options.store){ // 如果是根组件
this.$store = this.$options.store
}else { //如果是子组件
this.$store = this.$parent && this.$parent.$store
}
}
})
}
export default {
Store,
install
}
引入myVuex.js
import myVuex from './myVuex'
import Vue from 'vue'
Vue.use(myVuex)
export default new myVuex.Store({
state: {
num:0
},
mutations: {
numMutation:(state,arg) => {
state.num++
console.log(arg,state.num);
}
},
actions: {
numAction:({commit},arg) => {
setTimeout(() => {
commit('numMutation',arg)
},2000)
}
},
getters: {
numGetter:(state) => {
return state.num
}
}
})
示例
<!-- 测试示例 -->
<template>
<div class="Test">
<p>{{$store.getters['numGetter']}}</p>
<el-button @click="getters">getters</el-button>
<el-button @click="mutation">mutation</el-button>
<el-button @click="action">action</el-button>
</div>
</template>
<script>
export default {
methods: {
getters(){
console.log(this.$store.getters['numGetter']);
},
mutation(){
this.$store.commit('numMutation','mutation:')
},
action(){
this.$store.dispatch('numAction','action:')
}
}
}
</script>