背景: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 await
actions: {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 # 产品模块