基本用法
引入vuex
import Vuex from 'vuex'
Vue.use(Vuex)
创建store实例
const store = new Vuex.Store({
state:{
count:0
},
mutations:{
increment(state,n = 1){
state.count += n
}
},
actions:{
incrementAsync({commit}){
setTimeout(()=>{
commit("increment",2)
},2000)
}
},
getters: {
score(state) {
return `共扔出:${state.count}`
}
}
})
配置到Vue的根组件
new Vue({
store,
render: h => h(App),
}).$mount('#app')
界面上使用
<template>
<div>
<button @click="fire">扔一个</button>
<button @click="fireDouble">蓄力扔两个</button>
<h3>当前有:{{$store.state.count}}个</h3>
<h2>{{$store.getters.score}}</h2>
</div>
</template>
<script>
export default {
name:'vuexTest',
data(){
return {}
},
methods:{
fire(){
this.$store.commit('increment')
},
fireDouble(){
this.$store.dispatch('incrementAsync')
}
}
}
</script>
根据用法反推实现原理
- 这是一个插件,所以需要有
install
方法 - 需要有一个
Store
的类 - 需要实现
state
,mutations
,actions
,getters
- 实现数据响应式
实现
install方法
function install(_Vue){
Vue = _Vue
Vue.mixin({
beforeCreate(){
if(this.$options.store){
Vue.prototype.$store = this.$options.store
}
}
})
}
Store类
let Vue
class Store {
constructor(options){
this.state = new Vue({
data:options.state
})
this.mutations = options.mutations
this.actions = options.actions
options.getters && this.handleGetters(options.getters)
}
commit = (type,arg) => {
this.mutations[type](this.state,arg)
};
dispatch(type,arg){
this.actions[type]({commit:this.commit,state:this.state},arg)
}
handleGetters(getters){
this.getters = {}
Object.keys(getters).forEach(key => {
Object.defineProperty(this.getters,key,{
get:()=>{
return getters[key](this.state)
}
})
})
}
}
export default { Store, install };
验证
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a3239c181eb2311a2e01af24acd9753d.png)