Vuex的实现原理解析(最清晰)
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,可以帮助我们管理共享状态。
如何在Vue中使用Vuex?
如下先来回顾一下使用Vuex的正确姿势:
- 引入Vuex插件;
// store.js
Vue.use(Vuex);
- 将Vuex.Store这个类实例化,并传入一些配置,这里以计数器作为一个例子;
// store.js
const store = new Vuex.Store({state:{count:0},mutations:{increment(state){state.count++;},del(state){state.count--;},},actions:{asyncAdd({commit}){setTimeout(() => {commit("increment");}, 2000);}}
})
- 将store的实例配置给Vue
new Vue({store,render: h => h(App),
}).$mount('#app')
- 组件中使用时
<template><div>计数器<span>{{$store.state.count}}</span><br/><button @click="this.add">+</button><button @click="this.del">-</button><button @click="this.asyncAdd">异步+</button></div>
</template>
<script>
export default {methods:{add(){this.$store.commit('increment');},del(){this.$store.commit('del');},asyncAdd(){this.$store.dispatch('asyncAdd');}}
}
</script>
- 效果
页面上点击+时,调用this. s t o r e . c o m m i t ( " x x x " ) 方 法 , 实 现 t h i s . store.commit("xxx")方法,实现this. store.commit("xxx")方法,实现this.store.state.count的修改
Vuex的核心源码解析:
目标:
- 作为插件一定有install方法,可以在其中进行混入,当Vue实例化后挂载前拿到给其配置的store实例,把store放在原型上,以便全局可用;
- 持有基本的state,保存实例化router时配置的mutations,actions对象;
- 实现commit及dispatch等方法,可对state进行一定的修改;
Vuex的核心源码简版:
let Vue;
class Store {// 持有state,并使其响应化constructor(options){this.state = new Vue({data:options.state})this.mutations = options.mutations;// mutations 是对象this.actions = options.actions;// mutations 是对象// 绑定thisthis.commit=this.commit.bind(this);this.dispatch=this.dispatch.bind(this);}// 实现commit和dispatch方法commit(type,arg){this.mutations[type](this.state,arg);}dispatch(type,arg){console.log(this.actions[type])return this.actions[type](this,arg)}
}
function install(_vue){Vue = _vue;Vue.mixin({// 为什么用混入?use是先执行,而this指向的是vue实例,是在main.js中后创建的,使用混入才能在vue实例的指定周期里拿到store实例并做些事情beforeCreate(){if (this.$options.store) {Vue.prototype.$store=this.$options.store;}}})
}
export default {Store,install
}
其实,Vuex.Store是个类,使用他的时候,你给他传入了参数(state,mutations,actions)并让他实例化。你把这个实例配置给了Vue,Vuex帮你把他给了Vue原型上的$store。
Vuex还送给你个commit和dispatch方法让你能有办法改 s t o r e . s t a t e , 当 然 你 也 能 通 过 store.state,当然你也能通过 store.state,当然你也能通过store.state方法到你要的状态。