部署
工程目录下创建./store/index.js
//vuex store
//引入 Vuex , Vue
import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);
//准备 actions 用于响应组件中的动作
const actions = {};
//用于操作数据(state)
const mutations = {};
//用于存储数据
const state = {};
//创建 store 并暴露
export default new Vuex.Store({
actions,
mutations,
state,
});
在 main.js 中配置
import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";
import store from "./store/index.js";
Vue.config.productionTip = false;
Vue.use(Vuex);
new Vue({
render: (h) => h(App),
store,
}).$mount("#app");
使用
结构示意
各部分解释
- Actions 用于数据处理加工,然后 commit 到 multations 处理
- Mutations 与开发者工具相连,可在开发者工具中查看调试
- State 存储数据,可以理解为能动态响应的全局变量,各组件中都可获取
Actions 中相关
jiaJ(context, value) {
//console.log(context, value);
if (context.state.sum % 2) context.commit("JIA", value);
else context.dispatch("else",value)
},
else(context,value){...}
可接受两个参数,本别是 context
上下文和 value
数值,context
中有 dispatch
,commit
,state
等,如果逻辑代码较长,需要分布处理,可以使用 dispatch 递交给下一个逻辑处理函数,当所有处理函数处理完毕时,就可以使用 commit 提交到数据处理模块。当前状态下可以获取 state 中的变量并判断,但最好不要在这修改。
Mutations 相关
const mutations = {
JIA(state, value) {
state.sum += value;
},
JIAN(state, value) {
state.sum -= value;
},
};
纯纯的操作数据阶段,可获取两个参数 state
,value
,如果已知无逻辑判断,可以在组件中直接 commit 到这里,跳过 Actions 环节。Mutation 中的函数要大写以区分 Actions 中的函数
组件模板中
<template>
<div>
<h1> 当前求和为:{{ $store.state.sum }}</h1>
<select name="sel" id="sel" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add">+</button>
<button @click="minus">-</button>
<button @click="addOnlyJ"> 当前求和为奇数再加 </button>
<button @click="addWait"> 等一等再加 </button>
</div>
</template>
<script>
export default {
name: "A-count",
data() {
return {
n: 1,
};
},
methods: {
add() {
this.$store.commit("JIA", this.n);
},
minus() {
this.$store.commit("JIAN", this.n);
},
addOnlyJ() {
this.$store.dispatch("jiaJ", this.n);
},
addWait() {
this.$store.dispatch("jiaW", this.n);
},
},
};
</script>
<style>
</style>
- 模板中,使用{{$store.state.xxx}}获取变量
- 方法中,需要逻辑判断处理的,用
this.$store.disptch
交给 Actions 处理 - 不需要逻辑判断的,可以直接
this.$store.commit
交给 Mutations 处理
getters 配置项
配置
//getters 用于 state 中已有数据加工,返回新的数据,类似于 computed,优点是组件可复用
const getters = {
bigSum(state) {
return state.sum * 10;
},
};
//创建 store 并暴露
export default new Vuex.Store({
actions,
mutations,
state,
getters,
});
使用
<h1>getters.bigSum = {{ $store.getters.bigSum }}</h1>
mapState 与 mapGetters
引用原因
模板中重复出现 $store.state
和 $state.getters
导致模板不够简洁,所以需要用其他变量代替这个长表达式,例如 computed:
SUM(){return this.$store.state.sum;}
...more
但是变量太多又造成 computed 冗余,于是 mapState 和 mapGetters 出现了
使用
import { mapGetters, mapState } from "vuex";
...
computed: {
...mapState({ SUM: "sum", DATA: "data" }),
...mapGetters({ BIGSUM: "bigSum" }),
},
mapState 和 mapGetters 使用时提交对象,key 是新的变量名,value 是在 state 或者 getters 中的变量名,返回一个 Object:{ key : function },这样就与 computed 对应上了,key 就是那个计算属性名,function 就是计算函数,所以使用扩展运算符即可使用
简单表达
key 与 value 相同,可以直接用数组作为提交参数
mapState(['sum','data'])
mapMutations 与 mapActions
methods: {
// add() {
// this.$store.commit("JIA", this.n);
// },
// minus() {
// this.$store.commit("JIAN", this.n);
// },
...mapMutations({ add: "JIA", minus: "JIAN" }),
// addOnlyJ() {
// this.$store.dispatch("jiaJ", this.n);
// },
// addWait() {
// this.$store.dispatch("jiaW", this.n);
// },
...mapActions({ addOnlyJ: "jiaJ", addWait: "jiaW" }),
},
跟上面的 map 方法类似,可用数组形式简写,需要注意的是需要在模板@click 事件中传入参数
<button @click="add(n)">+</button>
<button @click="minus(n)">-</button>
<button @click="addOnlyJ(n)"> 当前求和为奇数再加 </button>
<button @click="addWait(n)"> 等一等再加 </button>
模块化 namespace
//vuex store
//引入 Vuex , Vue
import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);
const addOptions = {
namespaced:true,
actions: {
jiaJ(context, value) {
//console.log(context, value);
if (context.state.sum % 2) context.commit("JIA", value);
},
jiaW(context, value) {
setTimeout(() => {
context.commit("JIA", value);
}, 500);
},
},
mutations: {
JIA(state, value) {
state.sum += value;
},
JIAN(state, value) {
state.sum -= value;
},
},
state: {
sum: 0,
data: "HEllO",
},
getters: {
bigSum(state) {
return state.sum * 10;
},
},
};
//创建 store 并暴露
export default new Vuex.Store({
modules:{
addAbout:addOptions,
}
});
将 store/index.js 中的代码模块化拆分,方法如下
- 配置拆分对象
- namespaced 需要设置为 true
- 暴露时使用 modules
- 使用时在 map 类方法中加入一个命名空间参数
computed: {
...mapState("addAbout", { SUM: "sum", DATA: "data" }),
...mapGetters("addAbout", { BIGSUM: "bigSum" }),
},
methods: {
...mapMutations("addAbout", { add: "JIA", minus: "JIAN" }),
...mapActions("addAbout", { addOnlyJ: "jiaJ", addWait: "jiaW" }),
},
注意:模块化分类后
- 组件中使用 state 变量表达为
this.$store.state.分类名.变量名
- 组件中使用 getters 变量表达为
this.$store.getters[分类名/变量名]
- 组件中使用 commit/dispatch
this.$store.commit/dispatch('分类名/变量名',value)