前言:
Vuex中获取数据的辅助函数有两个:mapState和mapGetters,同样的vuex也提供了mapMutations 和mapActions方便操作mutations和actions方法
mapState用于将state中的数据映射到组件的计算属性中mapGetters用于将getter中的计算属性映射到组件的计算属性空中- 需要注意的是
mapState和mapGetter是映射为计算属性,获取数据 - 而
mapMutations和mapActions是映射为组件methods方法,修改数据的
1. 辅助函数说明:
- 之前的使用vue的方法并不是特别好.获取数据需要通过$store找到state对象,在获取数据,
- 操作getter,mutation,action也是如此,就会给使用带来不便
- vuex提供了一些辅助函数,帮助我们快速获取数据, 操作mutation,action函数
2. mapState
mapState是获取数据的辅助函数
2.1 获取数据说明
- 之前在使用vuex数据的时候我们都是在模板Mustache语法中直接获取数据,
- 这样的操作并不是特别友好,每一次都需要重新获取数据
- 因此比较常用的做法是将vuex中的数据获取后保存在组件的计算属性中
- 这样如果在组件中多次使用数据,就可以使用计算属性的缓存
之前获取数据示例代码
<div class="count">数字: {{ $store.state.count }}</div>
将数据保存在计算属性中,
示例代码如下
<template>
<div class="home">
<!-- 此时只需要使用计算看属性中的数据就可以了 -->
<div class="count">数字: {{ count }}</div>
</div>
</template>
<script>
export default {
name: 'Home',
data(){
},
computed:{
count(){
return this.$store.state.count
}
},
methods:{
}
}
</script>
2.2 计算属性中的问题
说明:
- 如果在一个组件中需要使用很多vuex中的状态
- 那么我们就需要在组件中定义所有的需要使用数据对应的计算属性
- 这样反而变的繁琐
示例代码
export default {
name: 'Home',
data(){
return {
// count: 0
}
},
computed:{
count(){
return this.$store.state.count
},
user(){
return this.$store.state.user
},
// ...
},
methods:{
}
}
2.3 使用mapState
为了解决组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余的问题.
vuex提供了mapState辅助函数帮助我们自动生成计算属性
注意:
使用mapState有不同使用方式
2.3.1 vuex中的状态
let store = new Vuex.Store({
state:{
count:0,
user:{
name:"张三",
age:20
},
fruits:[{
name:"苹果",
price: 22
},{
name:"梨子",
price: 25
},{
name:"西瓜",
price: 16
},{
name:"香蕉",
price: 18
}]
},
// ....
})
2.3.2 组件中计算属性名和vuex中的状态名不一致
说明:
- 例如组件中需要获取
vuex中count数据的内容, - 但是在组件中有可能也有一个名为
count的数据 - 因此在获取
vuex中的count时,组件的计算属性就不能在为count了, - 故而计算属性的名和
vuex状态名不一致
示例代码:
<template>
<div class="home">
<div class="count">vuex中数据: {{ number }}</div>
<div >组件自己的数据: {{ count }}</div>
</div>
</template>
<script>
// 从vuex中获取mapState
import {mapState} from 'vuex'
export default {
name: 'Home',
data(){
return {
count: 10
}
},
computed:mapState({
// 将vuex中状态count映射到组件计算属性number上
// 1. 普通使用
number: function(state){
return state.count
// this为当前组件实例
// return state.count + this.count
},
// 2. 简写方式
// number: state => state.count
// 3. 极简写法
// 字符串"count" 等价于 state => state.count
// number: 'count'
}),
}
</script>
示例说明:
- 计算属性的函数第一个参数为
vuex中的状态state,因此可以通过state直接获取数据 - 计算属性值为函数, 如果只是获取
vuex中数据并映射到组件就算属性上, 可以使用简写方式 - 如果在计算属性函数中需要使用组件自己的数据,或是有其他的逻辑操作,建议写完整函数
2.3.3 vuex状态名和计算名一样
说明:
- 如果vuex状态名和映射的组件计算名完全一样,
- mapState可以直接传字符串数组,来映射数据
实例代码:
<template>
<div class="home">
<div>vuex中count数据: {{ count }}</div>
<div>vuex中user数据: {{ user }}</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'Home',
data(){
return {
// count: 10
}
},
// 字符串数组的写法,
// 就是将vuex中的数据count,user
// 映射为组件计算属性count,user上
computed:mapState([
"count",
"user"
]),
}
</script>
2.3.4 组件有自己的计算属性
说明:
- 上面几个示例中,计算属性computed选项的值就是mapState
- 也就是组件的所有计算属性都是从
stroe映射过来的 - 那么如果还有一个自己额外的计算属性怎么办
- 如果需要给组件添加自定义的计算属性,就回归到以前的写法,mapState采用解构的方式使用
示例代码
<template>
<div class="home">
<div>vuex中数据: {{ count }}</div>
<div>vuex中数据: {{ user }}</div>
<div>组件计算属性值: {{ computePrice }}</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'Home',
data(){
return {
price: 10
}
},
computed:{
// 组件自己的计算属性
computePrice(){
return this.price * 2
},
// 通过mapState映射过来的计算属性
... mapState([
"count",
"user"
])
},
}
</script>
2.4 mapGetters的使用
说明:
mapGetters是vuex提供的将store中的getter映射到组件计算属性中的辅助函数mapGetters使用方式和mapState一样- 最常用的方式就是解构方式
示例代码如下:
<template>
<div class="home">
<div>{{fruits}}</div>
<div>{{filterFruits}}</div>
</div>
</template>
<script>
// 获取mapState, mapGetters 辅助函数
import {mapState,mapGetters} from 'vuex'
export default {
name: 'Home',
data(){
return {
price: 10
}
},
computed:{
computePrice(){
return this.price * 2
},
... mapState([
"count",
"user",
"fruits"
]),
// 解构mapGetters
// 将store中getters里filterFruits
// 映射到组件的filterFruits计算属性上
...mapGetters([
"filterFruits"
])
},
}
</script>
如果store中getters里的计算属性名和组件计算属性名不同时
可以采用对象的写法
...mapGetters([
// 组件中的计算属性名: getters中的计算属性名
fruits: "filterFruits"
])
3. 未使用辅助函数修改转台
3.1 设置修改状态的mutations和actions
代码如下
let store = new Vuex.Store({
state:{
count:0,
user:{
name:"张三",
age:20
},
fruits:[{
name:"苹果",
price: 22
},{
name:"梨子",
price: 25
},{
name:"西瓜",
price: 16
},{
name:"香蕉",
price: 18
}]
},
getters:{
filterFruits(state){
return state.fruits.filter(fruit => fruit.price > 20)
}
},
// 定义mutations
mutations:{
// 同步修改状态count
increment(state, payload){
state.count++
}
},
actions:{
// 异步修改状态count
asyncIncrement(context){
setTimeout(function(){
context.commit({
type:"increment"
})
},1000)
}
},
})
示例说明
- 组件中如果通过
commit触发mutation函数,就会同步更改状态count - 组件中如果通过
dispath异步触发action函数, - action会异步触发mutation函数,通过mutation修改状态
3.2 组件中触发mutation和action
<template>
<div class="home">
<div class="count">数字: {{ count }}</div>
<button @click="increment">同步++</button>
<button @click="asyncincrement">异步++</button>
</div>
</template>
<script>
// 获取辅助函数
import {mapState,mapGetters} from 'vuex'
export default {
name: 'Home',
data(){
return {
// count: 10
price: 10
}
},
computed:{
computePrice(){
return this.price * 2
},
... mapState([
"count",
"user",
"fruits"
]),
...mapGetters([
"filterFruits"
])
},
methods:{
increment(){
// 同步,通过commit触发mutation函数
this.$store.commit({
type:"increment"
})
},
asyncincrement(){
// 异步,通过dispatch 触发action函数
this.$store.dispatch({
type:"asyncIncrement"
})
}
}
}
</script>
示例说明:
- increment是触发mutation同步修改状态的方法
- asyncIncrement是触发action异步修改状态的方法
4. 使用mapMutations
说明:
- 之前如果我们需要在组件中修改store的状态都需要额外定义一个方法
- 如果这个方法里有大量的逻辑代码还好
- 如果这个方法只是为了触发mutation函数,每个组件都这样定义就会比较繁琐
- 因此vuex提供了
mapMutations辅助函数,可以将mutations函数映射为组件methods方法
4.1 方法同名
方法同名意思就是组件用来触发mutation函数的方法和mutation函数重名
就可以采用字符串数组的的方式将mutation函数通过函数名映射methods方法
数组里的字符串为mutations的函数名
代码如下:
// 通过vuex获取辅助函数
import {
mapState, // 获取state辅助函数
mapGetters, // 获取getters 辅助函数
mapMutations, // 操作mutations辅助函数
} from 'vuex'
export default {
name: 'Home',
data(){
return {
// count: 10
price: 10
}
},
computed:{
computePrice(){
return this.price * 2
},
... mapState([
"count",
"user",
"fruits"
]),
...mapGetters([
"filterFruits"
])
},
methods:{
...mapMutations([
'increment'
// 将this.increment 映射为 this.$store.commit("increment")
]),
asyncincrement(){
// 异步,通过dispatch 触发action函数
this.$store.dispatch({
type:"asyncIncrement"
})
}
}
}
4.2 关于载荷
此时是将mutation函数映射为组件methods方法,
如果此时调用这个方法不传参数时, 那么将没有载荷
例如:
<button @click="increment">同步++</button>
如果在调用这个映射方法是传递一个数据,那么这个数据将成为mutation函数的载荷
<button @click="increment(10)">同步++</button>
一般来说,载荷会选择对象方式传递数据
<button @click="increment({num:10})">同步++</button>
4.3 方法不同名
也就是需要映射到组件方法中的mutation函数,在组件中已经有同名的函数了
因此在映射时,就需要另外定义方法名
此时组件中被映射的方法名和mutation函数名就不同名了
此时需要选择对象的方式映射
代码如下:
// 通过vuex获取辅助函数
import {
mapState, // 获取state辅助函数
mapGetters, // 获取getters 辅助函数
mapMutations, // 操作mutations辅助函数
} from 'vuex'
export default {
name: 'Home',
data(){
return {
// count: 10
price: 10
}
},
computed:{
computePrice(){
return this.price * 2
},
... mapState([
"count",
"user",
"fruits"
]),
...mapGetters([
"filterFruits"
])
},
methods:{
...mapMutations({
// 方法名: mutation函数名
add:'increment'
// 将this.add 映射为 this.$store.commit("increment")
}),
asyncincrement(){
// 异步,通过dispatch 触发action函数
this.$store.dispatch({
type:"asyncIncrement"
})
}
}
}
5. 使用mapActions
mapActions辅助函数的使用和mapMutations一样
同样也可以传递载荷
因此可以将代码修改如下
// 通过vuex获取辅助函数
import {
mapState, // 获取state辅助函数
mapGetters, // 获取getters 辅助函数
mapMutations, // 操作mutations辅助函数
mapActions // 操作actions辅助函数
} from 'vuex'
export default {
name: 'Home',
data(){
return {
// count: 10
price: 10
}
},
computed:{
computePrice(){
return this.price * 2
},
... mapState([
"count",
"user",
"fruits"
]),
...mapGetters([
"filterFruits"
])
},
methods:{
...mapMutations({
// 方法名: mutation函数名
add:'increment'
// 将this.add 映射为 this.$store.commit("increment")
}),
...mapActions([
"asyncIncrement"
// 将this.asyncIncrement
// 映射为 this.$store.dispatch("asyncIncrement")
])
}
}
总结
四大辅助函数的使用
mapStatemapGettersmapMutationsmapActions