之前写了基础创建和组件间交互
从0开始创建vue3.0+vite+ts(一)
从0开始创建vue3.0+vite+ts之组件间传参(二)
今天讲讲 状态管理模式 vuex的使用
- vuex在vue3.0+使用
vuex在vue3.0+使用
// 引用vuex
npm install vuex --save
或
yarn add vuex --save
新建文件 store.ts
import { createStore } from "vuex"; // 创建一个新的 store 实例
export const store = createStore<object>({
state: {
msg: "这是默认store数据",
},
getters: {
getMsg: (state) => state.msg,
},
mutations: {
setMsg(state: object, msg: string) {
state.msg = msg;
},
},
actions: {
setMsg({ state, dispatch, commit }, msg: string) {
state.msg = msg;
},
},
});
方法一:直接引用store
在 index.vue 应用 store
<template>
<div>
<el-button @click="onCommit">commit</el-button>
<el-button type="primary" @click="onDispatch">dispatch</el-button>
msg = {{ msg }}; msg2 = {{ msg2 }}
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { store } from '@/store'
const msg = computed(() => store.state.msg)
const msg2 = computed(() => store.getters.getMsg)
function onCommit(v) {
store.commit('setMsg', '同步操作')
}
function onDispatch(v) {
store.dispatch('setMsg', '异步操作')
}
</script>
方法二:使用辅助函数mapActions, mapMutations, mapGetters, mapState
在 index.vue 应用辅助函数 mapActions, mapMutations, mapGetters, mapState 直接使用如下
<template>
<div>
<el-button @click="onCommit">commit</el-button>
<el-button type="primary" @click="onDispatch">dispatch</el-button>
msg = {{ msg }}; msg2 = {{ msg2 }}
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { mapActions, mapMutations, mapGetters, mapState } from 'vuex'
import { store } from '@/store'
const storeState = mapState(['msg'])
const storeGetters = mapGetters(['getMsg'])
const storeMutations = mapMutations(['setMsg'])
const storeActions = mapActions(['setMsg'])
const msg = computed(storeState.msg.bind({ $store: store }))
const msg2 = computed(storeGetters.getMsg.bind({ $store: store }))
function onCommit(v) {
storeMutations.setMsg.bind({ $store: store })('同步操作')
}
function onDispatch(v) {
storeActions.setMsg.bind({ $store: store })('异步操作')
}
</script>
看这有点复杂,优化一下,抽离封装 useStore.ts,并引入 useStore.ts
实现如下
import { computed } from "vue";
import { mapActions, mapMutations, mapGetters, mapState } from "vuex";
import { store } from "@/store";
export const useState = function (v: Array<string> | object) {
const data: object = {};
const state: object = mapState(v);
Object.keys(state).forEach((key) => {
data[key] = computed(state[key].bind({ $store: store }));
});
return data;
};
export const useGetters = function (v: Array<string> | object) {
const data: object = {};
const getters: object = mapGetters(v);
Object.keys(getters).forEach((key) => {
data[key] = computed(getters[key].bind({ $store: store }));
});
return data;
};
export const useMutations = function (v: Array<string> | object) {
const data: object = {};
const mutations: object = mapMutations(v);
Object.keys(mutations).forEach((key) => {
data[key] = mutations[key].bind({ $store: store });
});
return data;
};
export const useActions = function (v: Array<string> | object) {
const data: object = {};
const actions: object = mapActions(v);
Object.keys(actions).forEach((key) => {
data[key] = actions[key].bind({ $store: store });
});
return data;
};
上述还有优化空间,进一步优化 useStore.ts
import { computed } from "vue";
import { mapActions, mapMutations, mapGetters, mapState } from "vuex";
import { store } from "@/store";
function fn(v: Array<string> | object, m: object, type?: string) {
const data: object = {};
const fun: object = m(v);
Object.keys(fun).forEach((key) => {
if (type && (type === "state" || type === "getter")) {
data[key] = computed(fun[key].bind({ $store: store }));
} else {
data[key] = fun[key].bind({ $store: store });
}
});
return data;
}
export const useState = (v: Array<string> | object) => fn(v, mapState, "state");
export const useGetters = (v: Array<string> | object) => fn(v, mapGetters, "getter");
export const useMutations = (v: Array<string> | object) => fn(v, mapMutations);
export const useActions = (v: Array<string> | object) => fn(v, mapActions);
在 index.vue 应用看看效果
<template>
<div>
<el-button @click="onCommit">commit</el-button>
<el-button type="primary" @click="onDispatch">dispatch</el-button>
msg = {{ msg }}; msg2 = {{ msg2 }}
</div>
</template>
<script setup lang="ts">
import { useState, useGetters, useMutations, useActions } from '@/store/useStore'
const state = useState(['msg'])
const getters = useGetters(['getMsg'])
const mutations = useMutations(['setMsg'])
const actions = useActions(['setMsg'])
const msg: string = state.msg
const msg2: string = getters.getMsg
function onCommit(v) {
mutations.setMsg('同步操作')
}
function onDispatch(v) {
actions.setMsg('异步操作')
}
</script>
完美!!!就这样vuex你已经学会使用了