Vuex
状态管理工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import Vue from 'vue' import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({ state: { }, getters: { }, mutations: { }, actions: { }, modules: { } })
|
State
用来存储公共状态
组件直接调用 state 中的数据
也可以再计算属性中使用
1 2 3 4 5
| computed: { count() { return this.$store.state.count } }
|
辅助函数 - mapState
将 state 中的数据映射到组件的计算属性中
1 2 3 4 5 6 7 8
| import { mapState } form 'vuex'
export default { computed: { ...mapState(['count']) } }
|
mapState()
返回值为对象
1 2 3 4 5 6 7
| import { mapState } form 'vuex'
export default { computed: { ...mapState({myCount: 'count'}) } }
|
mapState()
除了接收数组以外,还可以接收对象
用于给 state 中的数据取别名
Getters
相当于store的计算属性,只有依赖值发生改变就会重新计算
1 2 3
| getters: { num: state => parseInt(state.count) }
|
组件中直接使用 getters 中的数据
也可以再计算属性中使用
1 2 3 4 5
| computed: { num() { return this.$store.getters.num } }
|
辅助函数 - mapGetters
1 2 3 4 5 6 7 8
| import { mapGetters } form 'vuex'
export default { computed: { ...mapGetters(['num']) } }
|
Mutations
操作 State 中的数据(只能执行同步代码),目的是形成数据快照
数据快照:一次 mutations 执行,立即生成一种视图状态
1 2 3 4 5 6 7 8
| state: { count: 0 }, mutations: { addCount(state, payload) { state.count += payload } }
|
参数:
- state:就是 Vuex 中的 state 对象
- payload:载荷(可以是任何形式的数据)
组件直接调用 mutations 方法
1 2 3 4 5
| methods: { addCount() { this.$store.commit('addCount', 1) } }
|
参数:
- 第一个参数:就是 mutations 方法名
- 第二个参数:就是载荷
使用对象风格传参
1 2 3 4 5 6 7 8
| methods: { addCount() { this.$store.commit({ type: 'addCount', num: 1 }) } }
|
1 2 3 4 5 6 7 8
| state: { count: 0 }, mutations: { addCount(state, payload) { state.count += payload.num } }
|
使用对象风格传参,就是将整个对象作为参数传给 payload
辅助函数 - mapMutations
将 mutations 中的方法映射在组件的 methods 中
1 2 3 4 5 6 7
| import { mapMutations } form 'vuex'
export default { methods: { ...mapMutations(['addCount']) } }
|
使用辅助函数调用 mutations 方法时,如果需要传入载荷,则需要在组件中调用方法时传入参数
1
| <button @click="addCount(1)"></button>
|
1 2 3 4 5 6 7
| import { mapMutations } form 'vuex'
export default { methods: { ...mapMutations({add: 'addCount'}) } }
|
mapMutations 函数同样支持对象格式传参,给方法取别名
Actions
执行异步操作
actions 提交的是 mutations 方法,而不是改变数据
1 2 3 4 5
| actions: { addCount(context, params) { context.commit('addCount', payload) } }
|
参数:
- context:==与 store 相同属性和方法的对象==
- payload:载荷
组件直接调用 actions 方法
1
| this.$store.dispatch('addCount', 1)
|
使用对象风格传参
1 2 3 4 5 6 7 8
| methods: { addCount() { this.$store.dispatch({ type: 'addCount', num: 1 }) } }
|
1 2 3 4 5 6 7 8
| state: { count: 0 }, actions: { addCount(context, payload) { context.commit('addCount', payload.num) } }
|
使用对象风格传参,就是将整个对象作为参数传给 payload
辅助函数 - mapActions
1 2 3 4 5 6 7
| import { mapActions } form 'vuex'
export default { methods: { ...mapActions(['addCount']) } }
|
传参方式与 mapMutations 函数相同
1 2 3 4 5 6 7
| import { mapActions } form 'vuex'
export default { methods: { ...mapActions({add: 'addCount'}) } }
|
mapActions 函数同样支持对象格式传参,给方法取别名
模块化
1 2 3 4 5 6 7
| store ├── index.js # 我们组装模块并导出 store 的地方 ├── actions.js # 根级别的 action ├── mutations.js # 根级别的 mutation └── modules ├── user.js # 用户模块 └── setting.js # 设置模块
|
modules
将 store 拆除多个模块,每个模块都有自己的 state、mutation、action、getter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| 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
1 2 3 4 5 6 7 8 9 10 11 12
| const user = { state: { }, getters: { }, mutations: { }, actions: { } }
export default user
|
./store/index.js
1 2 3 4 5 6 7 8 9 10 11
| 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
1 2 3 4 5 6 7 8 9 10 11
| user: { namespaced: true, state: { }, getters: { }, mutations: { }, actions: { } }
|
这样外部就不能直接调用 user 模块内部的 mutations、actions、getters
调用带命名空间的模块
- 带模块名调用
1
| this.$store.commit(['user/changeInfo'])
|
- 辅助函数带模块名调用
1 2 3 4 5 6 7 8 9 10
| import { mapMutations } from 'vuex' export default { methods: { ...mapMutations(['user/changeInfo'])
change() { this['user/changeInfo']() } } }
|
- createNamespacedHelpers
1 2 3 4 5 6 7 8 9
| import { createNamespacedHelpers } from 'vuex'
const { mapMutations } = createNamespacedHelpers('user')
export default { methods: { ...mapMutations(['changeInfo']) } }
|