Vuex多模块开发应用
Vuex多模块开发应用
背景
现在很多公司用Vue开发自己的产品,随着产品功能的不断扩展和增加,同时在项目中我们可能多人合作协同开发项目,那么带来一个很大的问题就是如何进行有效协同开发,提高开发效率,增强项目的可维护性和扩展性。还好我们有个好的解决方案,可以进行模块化开发,提升开发效率。以Vuex的模块化为例:
使用 Vuex 的module
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 的状态
module 的命名空间的高级用法
// 文件A
export default {
namespaced: true, // 命名空间避免重名
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
// 文件B
export default {
namespaced: true,
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
// 在moduleA文件引入文件A、文件B
import A from './A'
import B from './B'
export default {
A,
B
}
//在入口文件引入状态管理器
import moduleA from './moduleA'
import moduleB from './moduleB' // 自己定义
import moduleC from './moduleC' // 自己定义
new Vuex.Store({
modules: {
...moduleA, // 模块A
...moduleB, // 模块B
...moduleC // 模块C
}
})
Vuex 使用的小技巧
State仓库字段太多怎么维护 —— 使用函数
state有时候可能几十个字段,有些字段代表不一样的应用,我们可以使用函数来封装,返回一个对象,再使用 Object.assign
合并对象
const initTableField = () => { // 表格字段
return {
id: '',
name: '',
password: '',
username: '',
number: false,
sort: false,
tel: false,
email: [],
....
}
}
const shopData = () => { // 商品字段
return {
price: '',
goods: [],
name: [],
param: {
searchValue: {},
page: {},
pageSize: {},
title: ''
},
....
}
const initState = () => {
return Object.assign(initTableField(), shopData(), {
...
})
}
const state = initState()
使用mapState, mapGetters, mapMutations, mapActions 辅助函数减少代码量
mapState
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
mapGetters
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
mapMutations辅助函数
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
mapActions辅助函数
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')`
})
}
}
模块中使用辅助函数
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default {
computed: {
...mapState('模块名', ['A', 'B', 'state变量']),// mapState为例
...mapGetters('模块名', ['A', 'B', 'getters变量']) // mapGetters为例
},
methods: {
...mapMutations('模块名', ['A', 'B', 'mutations方法名']),// mapMutations 为例
...mapActions('模块名', ['A', 'B', 'actions方法名']) // mapActions 为例
}
}
在actions中使用 async/await 控制异步执行方法
actions可以定义异步方法,如果要控制异步接口的执行顺序,可以使用 async/await
实现:
export default {
actions: {
async FUNCTIONA ({state, commit}, data) {
let result1 = await Func1(); // 调用异步方法Func1
let result2 = await Func2(); // 调研员异步方法Func2
... // 执行逻辑代码
}
}
}