Vuex
Vuex
状态管理工具
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {},
modules: {},
});
State
用来存储公共状态
state: {
count: 0;
}
组件直接调用 state 中的数据
this.$store.state.count;
也可以再计算属性中使用
computed: {
count() {
return this.$store.state.count
}
}
辅助函数 - mapState
将 state 中的数据映射到组件的计算属性中
import { mapState } form 'vuex'
export default {
computed: {
/* 拓展运算符 */
...mapState(['count'])
}
}
mapState()
返回值为对象
import { mapState } form 'vuex'
export default {
computed: {
...mapState({myCount: 'count'})
}
}
mapState()
除了接收数组以外,还可以接收对象
用于给 state 中的数据取别名
Getters
相当于 store 的计算属性,只有依赖值发生改变就会重新计算
getters: {
num: (state) => parseInt(state.count);
}
组件中直接使用 getters 中的数据
this.$store.getters.num;
也可以再计算属性中使用
computed: {
num() {
return this.$store.getters.num
}
}
辅助函数 - mapGetters
import { mapGetters } form 'vuex'
export default {
computed: {
/* 拓展运算符 */
...mapGetters(['num'])
}
}
Mutations
操作 State 中的数据(只能执行同步代码),目的是形成数据快照
数据快照:一次 mutations 执行,立即生成一种视图状态
state: {
count: 0
},
mutations: {
addCount(state, payload) {
state.count += payload
}
}
参数:
- state:就是 Vuex 中的 state 对象
- payload:载荷(可以是任何形式的数据)
组件直接调用 mutations 方法
methods: {
addCount() {
this.$store.commit('addCount', 1)
}
}
参数:
- 第一个参数:就是 mutations 方法名
- 第二个参数:就是载荷
使用对象风格传参
methods: {
addCount() {
this.$store.commit({
type: 'addCount',
num: 1
})
}
}
state: {
count: 0
},
mutations: {
addCount(state, payload) {
state.count += payload.num
}
}
使用对象风格传参,就是将整个对象作为参数传给 payload
辅助函数 - mapMutations
将 mutations 中的方法映射在组件的 methods 中
import { mapMutations } form 'vuex'
export default {
methods: {
...mapMutations(['addCount'])
}
}
使用辅助函数调用 mutations 方法时,如果需要传入载荷,则需要在组件中调用方法时传入参数
<button @click="addCount(1)"></button>
import { mapMutations } form 'vuex'
export default {
methods: {
...mapMutations({add: 'addCount'})
}
}
mapMutations 函数同样支持对象格式传参,给方法取别名
Actions
执行异步操作
actions 提交的是 mutations 方法,而不是改变数据
actions: {
addCount(context, params) {
context.commit('addCount', payload)
}
}
参数:
- context:与 store 相同属性和方法的对象
- payload:载荷
组件直接调用 actions 方法
this.$store.dispatch("addCount", 1);
使用对象风格传参
methods: {
addCount() {
this.$store.dispatch({
type: 'addCount',
num: 1
})
}
}
state: {
count: 0
},
actions: {
addCount(context, payload) {
context.commit('addCount', payload.num)
}
}
使用对象风格传参,就是将整个对象作为参数传给 payload
辅助函数 - mapActions
import { mapActions } form 'vuex'
export default {
methods: {
...mapActions(['addCount'])
}
}
传参方式与 mapMutations 函数相同
import { mapActions } form 'vuex'
export default {
methods: {
...mapActions({add: 'addCount'})
}
}
mapActions 函数同样支持对象格式传参,给方法取别名
模块化
store
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
└── modules
├── user.js # 用户模块
└── setting.js # 设置模块
modules
将 store 拆除多个模块,每个模块都有自己的 state、mutation、action、getter
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const user = {
state: {},
getters: {},
mutations: {},
actions: {},
};
export default new Vuex.Store({
modules: {
user,
setting: {
state: {},
getters: {},
mutations: {},
actions: {},
},
},
});
./store/modules/moduleA.js
const user = {
state: {},
getters: {},
mutations: {},
actions: {},
};
export default user;
./store/index.js
import Vue from "vue";
import Vuex from "vuex";
import user from "./modules/user";
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
user,
},
});
可以将每个 module 拆成一个文件,单独编写,提高独立性
最后由 ./store/index.js 统一导入、抛出
命名空间
namespaced
默认情况下,模块下的 state、getters、actions、mutations 都是全局命名空间
也就是在全局都可以直接调用
如果需要实现高封闭性,这需要设置命名空间namespaced: true
user: {
namespaced: true,
state: {
},
getters: {
},
mutations: {
},
actions: {
}
}
这样外部就不能直接调用 user 模块内部的 mutations、actions、getters
调用带命名空间的模块
- 带模块名调用
this.$store.commit(["user/changeInfo"]);
- 辅助函数带模块名调用
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations(['user/changeInfo'])
change() {
this['user/changeInfo']()
}
}
}
- createNamespacedHelpers
import { createNamespacedHelpers } from "vuex";
const { mapMutations } = createNamespacedHelpers("user");
export default {
methods: {
...mapMutations(["changeInfo"]),
},
};