vuex 的实现原理
程序员文章站
2022-04-02 21:14:04
...
vuex 的实现:
- 在vue项目中先安装vuex
- 利用vue的插件机制,使用Vue.use(vuex)时,会调用vuex的install方法,装载vuex
- 使用vue的mixin混入机制,在beforeCreate钩子函数前混入,全局注入store,让每一个组件和实例,都能访问到 $store,来实现组件间的状态共享
VueX 源码图解如下:
示例代码实现:
main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App),
}).$mount('#app')
store.js
import Vue from 'vue'
import Vuex, {Store} from './vuex'
Vue.use(Vuex);
const state = {
count: 10,
val: 2
}
const getters = {
result(state, getters){
return state.count * state.val;
},
result2(state, getters){
return state.count / state.val;
}
}
const mutations = {
modify(state, value){
state.count = value;
}
}
const actions = {
requestModifyCount(context, value){
setTimeout(() => {
context.commit('modify', value);
}, 2000);
}
}
// const store = new Vuex.Store({
const store = new Store({
state,
getters,
mutations,
actions
});
export default store;
vuex 文件下的 index.js
let Vue = null;
export default class Vuex{
static install(_Vue){
Vue = _Vue;
// 混入,为了每一个组件和实例,都能访问到$store,前提是根实例配置了store
Vue.mixin({
beforeCreate(){
if(this.$root.$options.store){
this.$store = this.$root.$options.store;
}
}
})
}
}
export class Store{
constructor({state, getters, mutations, actions}){
this._state = state;
this._getters = getters;
this._mutations = mutations;
this._actions = actions;
// 转换实例将要使用的计算属性
let obj = {};
Object.entries(getters).forEach(([key, value])=>{
obj[key] = ()=>{
return value(state, obj);
}
})
// 构建实例
this._vm = new Vue({
data: state,
computed: obj
});
// 处理data,转为store.state
this.state = this._vm.$data;
// 构建getters
this._handleGetters();
}
_handleGetters(){
//$store._vm.result $store.getters.result
this.getters = {};
Object.keys(this._getters).forEach(key=>{
Object.defineProperty(this.getters, key, {
enumerable: true,
configurable: true,
get: ()=>{
return this._vm[key];
}
});
})
}
commit(name, payload){
//调用插件,提醒开发者数据的变化流程
this._mutations[name](this.state, payload);
}
dispatch(name, payload){
// 使用promise做封装
this._actions[name](this, payload);
}
}
Vuex.Store = Store;
Vuex 应用场景:
- 多个视图依赖于同一个状态
- 来自不同视图的行为需要变更同一个状态
上一篇: 那十块钱我买鸭脖吃啦
下一篇: 请珍惜对那些对你好的人