背景:vuex store的进阶版 实用于大型简单的单页利用
用处:数据管理
state 相似于 data
存储全局状态值,当扭转值会触发dom更新, 应用时挂载在子组件的computed计算属性上(这样的目标是为了实时更新)
mapState
getters
getters 能够返回一个值(属性),也可返回一个办法函数
拜访办法时 每次进行调用 不会缓存后果
拜访属性时 作为vue响应式零碎的一部分缓存起来
mapGetters --辅助函数
将store中的getter映射到部分计算属性,即 定义getter后 在总的vuex去注入这个getter 从而在全局进行应用
mutations
用于更改store中的状态值 蕴含一个事件类型和一个回调函数 不反对异步
mutations: { increment (state, n) { state.count += n }}store.commit('increment', 10)// 以对象模式传参mutations: { increment (state, payload) { state.count += payload.amount }}// amount相当于传入参数store.commit('increment', { amount: 10})
actions
相似于mutations 反对异步 通过 store.dispatch 触发
actions: { incrementAsync ({ commit }) { setTimeout(() => { commit('increment') }, 1000) }}// 两种模式散发调用store.dispatch('incrementAsync', { amount: 10})store.dispatch({ type: 'incrementAsync', amount: 10})
mapActions
在组件中应用 this.$store.dispatch('xxx') 散发 action,或者应用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(须要先在根节点注入 store)
import { mapActions } from 'vuex'export default { // ... methods: { ...mapActions([ 'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')` // `mapActions` 也反对载荷: 'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)` ]), ...mapActions({ add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')` }) }}
actions 异步
actions: { actionA ({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { commit('someMutation') resolve() }, 1000) }) }}// 一般调用模式store.dispatch('actionA').then(() => { // ...})// 在别的action中调用actions: { // ... actionB ({ dispatch, commit }) { return dispatch('actionA').then(() => { commit('someOtherMutation') }) }}// async awaitactions: { async actionA ({ commit }) { commit('gotData', await getData()) }, async actionB ({ dispatch, commit }) { await dispatch('actionA') // 期待 actionA 实现 commit('gotOtherData', await getOtherData()) }} // 假如 getData() 和 getOtherData() 返回的是 Promise
modules
作用:将store宰割成模块,每个模块领有本人的 state、mutation、action、getter
const moduleA = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { ... }}const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... }}const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB }})store.state.a // -> moduleA 的状态store.state.b // -> moduleB 的状态
const moduleA = { state: () => ({ count: 0 }), mutations: { increment (state) { // 这里的 `state` 对象是模块的部分状态 state.count++ } }, getters: { doubleCount (state) { return state.count * 2 } }}
const moduleA = { state: () => ({ count: 0 }), mutations: { increment (state) { // 这里的 `state` 对象是模块的部分状态 state.count++ } }, getters: { doubleCount (state) { return state.count * 2 } }, actions: { incrementIfOddOnRootSum ({ state, commit, rootState }) { if ((state.count + rootState.count) % 2 === 1) { commit('increment') } } }, getters: { sumWithRootCount (state, getters, rootState) { return state.count + rootState.count } },}
还有模块命名 模块继承 和更多简单用法 详见:
https://vuex.vuejs.org/zh/gui...
总结
1.利用层级的状态应该集中到单个 store 对象中。
2.提交 mutation 是更改状态的惟一办法,并且这个过程是同步的。
3.异步逻辑都应该封装到 action 外面。
如果 store 文件太大,需将 action、mutation 和 getter 宰割到独自的文件
我的项目架构
├── index.html├── main.js├── api│ └── ... # 抽取出API申请├── components│ ├── App.vue│ └── ...└── store ├── index.js # 咱们组装模块并导出 store 的中央 ├── actions.js # 根级别的 action ├── mutations.js # 根级别的 mutation └── modules ├── cart.js # 购物车模块 └── products.js # 产品模块