四个 Map 方法的使用
# 四个 Map 方法的使用
在使用 Vuex 时,我们通常需要在组件中访问和修改全局状态数据。为了简化这种映射操作,Vuex 提供了四个辅助函数:mapState
、mapGetters
、mapActions
和 mapMutations
。这些辅助函数允许我们使用简单的方法将 Vuex 的 state
、getters
、actions
和 mutations
映射到组件的计算属性或方法中,这样我们每次去访问和修改全局状态数据的时候,就不需要去调用Store 实例的方法了。
# 为什么需要 Map 方法
- 简化调用:映射后,直接以计算属性和方法的形式在组件中使用,而无需显式调用
this.$store
。 - 提高可读性:通过这些辅助函数,代码结构更清晰,便于理解和维护。
- 更易于维护:使状态管理和组件逻辑解耦,更容易进行更改和扩展。
扩展运算符的使用
在这些辅助函数中,通常会用到 JavaScript 的 扩展运算符(...
),它允许我们快速展开一个对象或数组的元素,便于将 Vuex 中的状态或方法直接映射到组件内。
对象展开:将对象的所有属性展开到另一个对象中。
let obj1 = { a: 1, b: 2 }; let obj2 = { ...obj1, c: 3 }; // obj2: { a: 1, b: 2, c: 3 }
1
2数组展开:将数组的所有元素展开到另一个数组中。
let arr1 = [1, 2, 3]; let arr2 = [...arr1, 4, 5]; // arr2: [1, 2, 3, 4, 5]
1
2
# 使用 Map 方法的原理
在使用 Vuex 的 mapState
、mapGetters
、mapActions
和 mapMutations
时,我们可以通过数组或对象的形式输入 Vuex 中定义的属性或方法。这些辅助函数会将 Vuex 的全局状态或方法映射为组件中的计算属性或方法。
- 数组写法:
- 直接使用 Vuex 中定义的属性或方法名。这种方式适用于映射后名称不需要更改的情况。
- 示例:
...mapState(['sum', 'school', 'subject'])
,将state
中的sum
、school
、subject
映射为同名的计算属性。
- 对象写法:
- 用于重命名映射后的属性或方法。对象的属性名是映射后新的名称,属性值是 Vuex 中定义的原名称。
- 示例:
...mapState({ total: 'sum', mySchool: 'school', major: 'subject' })
,将state.sum
映射为total
,state.school
映射为mySchool
,state.subject
映射为major
。
转换过程
- 这些
map
函数根据输入的数组或对象生成一个新的对象,该对象包含需要映射的属性或方法。 - 在对象写法中,每个属性名是映射后的新名称,而属性值对应 Vuex 中的原属性或方法名称。
使用展开运算符
- 将
map
函数返回的新对象通过展开运算符(...
)合并到组件的computed
或methods
中。 - 这样,映射后的属性或方法可以作为组件的计算属性或方法来使用。
# 1. mapState
mapState
用于将 state
中的数据映射为组件的计算属性。它帮助我们将 Vuex 的全局 state
快速映射为局部计算属性。
import { mapState } from 'vuex';
computed: {
// 对象写法:将 state 中的属性映射为计算属性
...mapState({
sum: 'sum', // 映射 this.$store.state.sum 为计算属性 this.sum
school: 'school', // 映射 this.$store.state.school 为计算属性 this.school
subject: 'subject' // 映射 this.$store.state.subject 为计算属性 this.subject
}),
// 数组写法:简化写法,直接映射同名属性
...mapState(['sum', 'school', 'subject']) // 自动将 state 中同名属性映射为 this.sum, this.school, this.subject
}
2
3
4
5
6
7
8
9
10
11
12
13
- 在组件中使用:通过计算属性直接使用映射的
state
数据,例如:this.sum
、this.school
。
# 2. mapGetters
mapGetters
用于将 getters
中的数据映射为组件的计算属性。类似于 mapState
,但针对 getters
中的属性。
import { mapGetters } from 'vuex';
computed: {
// 对象写法:将 getters 中的方法映射为计算属性
...mapGetters({
bigSum: 'bigSum' // 映射 this.$store.getters.bigSum 为计算属性 bigSum
}),
// 数组写法:简化写法,直接映射
...mapGetters(['bigSum']) // 自动将 getters 中同名方法映射为 this.bigSum
}
2
3
4
5
6
7
8
9
10
11
- 在组件中使用:通过计算属性直接使用映射的
getters
数据,例如:this.bigSum
。
# 3. mapActions
mapActions
用于将 actions
映射为组件的方法。actions
通常用于异步操作和业务逻辑处理。
import { mapActions } from 'vuex';
methods: {
// 对象写法:将 actions 中的方法映射为组件的方法
...mapActions({
incrementOdd: 'jiaOdd', // 映射 this.$store.dispatch('jiaOdd') 为方法 incrementOdd
incrementWait: 'jiaWait' // 映射 this.$store.dispatch('jiaWait') 为方法 incrementWait
}),
// 数组写法:简化写法,直接映射
...mapActions(['jiaOdd', 'jiaWait']) // 自动将 actions 中同名方法映射为 this.jiaOdd, this.jiaWait
}
2
3
4
5
6
7
8
9
10
11
12
- 在组件中使用:通过方法调用来触发
actions
,例如:this.incrementOdd()
、this.jiaOdd()
;如果要传递参数,可以使用this.jiaOdd(5)
,等价于this.$store.dispatch('jiaOdd', 5)
。
注意
在调用mapActions映射的方法的时候,如果不传参数,默认的第一个参数是事件对象,也就是说this.jiaOdd()
等价于this.$store.dispatch('jiaOdd', event)
。
# 4. mapMutations
mapMutations
用于将 mutations
映射为组件的方法。mutations
用于同步修改 state
中的数据。
import { mapMutations } from 'vuex';
methods: {
// 对象写法:将 mutations 中的方法映射为组件的方法
...mapMutations({
increment: 'JIA', // 映射 this.$store.commit('JIA') 为方法 increment
decrement: 'JIAN' // 映射 this.$store.commit('JIAN') 为方法 decrement
}),
// 数组写法:简化写法,直接映射
...mapMutations(['JIA', 'JIAN']) // 自动将 mutations 中同名方法映射为 this.JIA, this.JIAN
}
2
3
4
5
6
7
8
9
10
11
12
- 在组件中使用:通过方法调用来触发
mutations
,例如:this.increment()
、this.JIA()
;如果要传递参数,可以使用this.JIA(5)
,等价于this.$store.commit('JIA', 5)
。
注意
在调用mapMutations映射的方法的时候,如果不传参数,默认的第一个参数是事件对象,也就是说this.JIA()
等价于this.$store.commit('JIA', event)
。
使用注意事项
- 参数传递:使用
mapActions
和mapMutations
时,如果需要传递参数,可以在模板中绑定事件时传递参数。否则,默认参数为事件对象。 - 组合使用:
mapState
和mapGetters
用于computed
,mapActions
和mapMutations
用于methods
。