(一)VUEX里面的属性有:
| 属性 | 解释 |
|---|---|
| state | 存储数据的 获取数据最好推荐使用getters 硬要使用的话可以用MapState, 先引用,放在compute中 ...mapState(['方法名','方法名']) |
| getters | 获取数据的:this.$store.getters.xxx也可使用mapGetters 先引用,放在compute中, ...mapGetters(['方法名','方法名']) |
| mutations | 同步操作数据的:this.$store.commit(“方法名”,数据)也可使用mapMutations ,使用方法和以上一样 |
| actions | 异步操作数据的:this.$store.dispatch(“方法名”,数据)也可使用mapActions ,使用方法和以上一样 |
| modules | 板块,里面可以放多个vuex |
- 我们使⽤state定义数据,
- 使⽤mutation定义修改数据的逻辑,并且在组件中使⽤commit去调⽤mutations。
- 在此基础之上,还可以⽤getters去实现Vuex世界的计算属性,
- 使⽤action来去定义异步任务,并且在内部调⽤mutation去同步数据。
(二)实现原理(vue3版)
// mini-vuex.js
import { inject, reactive, computed } from 'vue';
const STORE_KEY = '__store__';
function useStore() {
return inject(STORE_KEY);
}
// 暴露createStore去创建Store的实例
function createStore(options) {
return new Store(options);
}
class Store {
constructor(options) {
this.$options = options;
// Store类内部变量_state存储响应式数据
this._state = reactive({ data: options.state() }); //获取传入的state,变成响应式
this._mutations = options.mutations; //获取传入的mutations
this._actions = options.actions;
// getters
this.getters = {};
Object.keys(options.getters).forEach(name => {
const fn = options.getters[name]; //获取⽤⼾配置好的getters
//用computed包裹,将getters的内容变成计算属性
this.getters[name] = computed(() => fn(this.state));
});
}
// 【state方法实现】:读取state的时候直接获取响应式数据 _state.data
get state() {
return this._state.data;
}
// 【commit方法实现】:提供commit函数去执⾏⽤⼾配置好的mutations。
commit = (type, payload) => {
console.log('【 type, payload 】-30', type, payload);
// type:commit传入的方法名
const entry = this._mutations[type]; //获取⽤⼾配置好的mutations
entry && entry(this.state, payload);
};
// 【dispatch方法实现】:提供commit函数去执⾏⽤⼾配置好的mutations。
dispatch(type, payload) {
const entry = this._actions[type]; //获取⽤⼾配置好的actions
return entry && entry(this, payload);
}
// 为了让useStore能正常 ⼯作,我们需要给store新增⼀个install⽅法,
// 这个⽅法会在app.use函数内部执⾏。我们通过app.provide函数注册store给全局的组件使⽤。
install(app) {
// provide注册了数据后,所有的⼦组件都可以通过inject获取数据,
app.provide(STORE_KEY, this);
}
}
export { createStore, useStore };
使用
import { createStore } from './mini-vuex'
const store = createStore({
state() {
return { count: 666 };
},
// vuex的计算属性
getters: {
double(state) {
return state.count * 2;
}
},
// mutations:同步修改数据, mutation内部的函数会把state作为参数,
mutations: {
add(state) {
// 我们直接操作state.count就可以完成数据的修改。
state.count++;
}
},
// mutations:异步修改数据
actions: {
// 这个配置中所有的函数,可以通过解构获得 commit函数。
// 内部的异步任务完成后,就随时可以调⽤commit来执⾏mutations去更新数据。
asyncAdd({ commit }) {
setTimeout(() => {
commit('add'); //可以调⽤commit来执⾏mutations去更新数据。
}, 1000);
}
}
});
export default store;
[ 延伸问题 ]
1. vuex中 this.$store.dispatch() 与 this.$store.commit()方法的区别?
区别主要是存取方式的不同,两个方法都是传值给vuex的mutation改变state,可以不走dispatch ,直接commit到mutations
this.$store.dispatch():异步操作- 写法:
this.$store.dispatch('action方法名',值) - 含有异步操作,在actions方法里面通过commit调用mutation中的方法,把值赋给state中的字段
- 写法:
this.$store.commit():同步操作- 写法:
this.$store.commit(‘mutations方法名’,值) - 直接提交commit修改state中的值
- 写法: