vuex是一个插件,插件会暴露出一个install方法,在Vue.use的时侯会先调用这个install方法,生成一个实例,我们可以在beforeCreate生命周期钩子函数里面来初始化一些内容
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
info: {
name: 'boobey',
age: 29
}
},
getters: {
getName(state) {
let num = state.info.age + 1
return num
}
},
mutations: {
changeName(state, playod) {
state.info.name += playod
}
},
actions: {
subMutat(context, playod) {
console.log(context)
let {commit,dispatch}=context
commit('changeName', playod)
}
},
modules: {}
})
在store/index.js中我们可以看到,import Vuex from 'vuex',并且还new 了一个Vue.Store(...),接下来我们来写这个vuex插件,里面要包含两块内容,一个install方法,一个Store方法,Store方法是一个构造函数或者是一个class类,这里我们用calss类来写,新建一个文件store/vuex.js,store/index.js里面记得修改路经import Vuex from './vuex.js'
let Vue;//定义一个Vue
class Store {
constructor(options){
console.log(this)
this.vm=new Vue({//让state变成响应式的
data:{
state:options.state
}
})
//getters
let getters=options.getters
this.getters={}
Object.keys(getters).forEach(item=>{
Object.defineProperty(this.getters,item,{
get:()=>{
return getters[item](this.state)
}
})
})
//mutations
let mutations=options.mutations
this.mutations={}
Object.keys(mutations).forEach(item=>{
this.mutations[item]=(playod)=>{
mutations[item](this.state,playod)
}
})
//actions
let actions=options.actions
this.actions={}
Object.keys(actions).forEach(item=>{
this.actions[item]=(playod)=>{
actions[item](this,playod)
}
})
}
commit=(type,playod)=>{
this.mutations[type](playod)
}
dispatch=(type,playod)=>{
this.actions[type](playod)
}
get state(){
return this.vm.state
}
}
const install = (v) => { //v其实是一个Vue这个构造函数,当我们Vue.use时,会自动传进去的,console.log(v)可以看到是Vue这个构造函数
Vue = v
Vue.mixin({//用来混合实例对象
beforeCreate() {
//初始化$store,使每个组件都可以访问$store
if (this.$options && this.$options.store) {//如果这个条件成立,说明这个组件是根组件,即根实例,$options就是new Vue({...})里面的{...}配置项,因为在main.js中的配置项里才有store
this.$store=this.$options.store
}else if(this.$parent&&this.$parent.$store){//如果不是根组件是就用父组件的$store
this.$store=this.$parent.$store
}
},
})
}
export default {
install,
Store,
}
其中用到了mixin这个方法详细这里有介绍:混入 — Vue.js
接下来就可以正常调用了,在组件中
<template>
<div class="home">
<div>
state:{{ this.$store.state.info.name }}
<br />
getters:{{this.$store.getters.getName}}
<br>
<button @click="Mchange">mutations修改</button>
<button @click="Achange">actions修改</button>
</div>
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: "HomeView",
components: {
},
methods: {
Mchange(){
this.$store.commit('changeName',1)
},
Achange(){
this.$store.dispatch('subMutat',2)
}
},
};
</script>