再提一个需求:我在bilibili
学Vue
把这俩个属性都存在vuex
里然后读出来做展示:
store > index.js
//准备state:用于存储数据
const state = {
sum:0,
school:'bilibili',
subject: 'Vue'
}
Add.vue
<h4>我在{{$store.state.school}},学习{{$store.state.subject}}</h4>
这个时候功能实现了
你有没有发现使用Vuex里面很多数据的时候,一直都是在写$store.state
这段代码?
这一遍一遍的写是否不好。 我们的目标是直接写school和subject ,这问题怎么办。
-
可以使用计算属性来写:
<template> <div> .... <h4>我在{{school}},学习{{subject}}</h4> </div> </template> <script> export default{ .... computed:{ sum(){ return this.$store.state.sum }, school(){ return this.$store.state.school }, subject(){ return this.$store.state.subject }, bigSum(){ return this.$store.getters.bigSum } }, } </script>
觉不觉得计算属性里的形式很固定?
每一个人都要说一下计算属性名和都要说一下自己读取的是state里的哪个数据
是不是觉得
return this.$store
代码是一样的Vuex的作者能不能给我们一个方法批量去生成
return this.$store
?从Vuex身上引出
mapState
(映射状态),要求你把方法名
和值
告诉它import {mapState} from 'vuex' ... mounted(){ //console.log('Add',this.$store) //里面要传入一个对象 const x = mapState({{sum:'sum',school:'school',subject:'subject'}}) console.log(x) }, ...
看看这个x到底是啥:
{sum: ƒ, school: ƒ, subject: ƒ} school: ƒ mappedState() subject: ƒ mappedState() sum: ƒ mappedState() [[Prototype]]: Object
computed:{ //...:代表把对象里面的每一组k-v分开和放在对象里面 //也就是把sum、school、subject都分开放到这里面了 //借助mapState生成计算属性,从state中读取数据(对象写法) ...mapState({sum:'sum',school:'school',subject:'subject'})//写这个查看时Vue开发者工具会显示vuex bindings(这个没有简写形式) },
就相当于你写了:
computed:{ sum(){ return this.$store.state.sum }, school(){ return this.$store.state.school }, subject(){ return this.$store.state.subject }, bigSum(){ return this.$store.getters.bigSum } },
mapState数组写法:
...mapState(['sum','school','subject']),
但是这样写的坏处就是如果方法与值不同名就会找不到值得问题
用数组得写法就是要生成得计算属性名与state里的值得是同名的
-
既然有
mapState
那还有mapGetters
computed:{
...mapState(['sum','school','subject']),
...mapGetters(['bigSum'])
},
总结
mapState方法:用于帮我们映射state
中的数据为计算属性
computed(){
//借助mapState生成计算属性: sum、school、subject(对象写法)
...mapState({sum:'sum',school:'school',subject:'subject'}),
//借助mapState生成计算属性: sum、school、subject(数组写法)
...mapState(['sum','school','subject'])
}
mapGetters方法: 用于帮助我们映射getters
中的数据为计算属性
computed(){
//借助mapGetters生成计算属性: bigSum(对象写法)
...mapState({bigSum:'bigSum'}),
//借助mapGetters生成计算属性: bigSum(数组写法)
...mapState(['bigSum'])
}
methods: {
add(){
this.$store.commit('jia',this.n)
},
jf(){
this.$store.commit('jian',this.n)
},
/************************** */
jAdd(){
this.$store.dispatch('jadd',this.n)
},
delayAdd(){
this.$store.dispatch('delayAdd',this.n)
}
},
跟mapState
差不多,就是名字是mapMutations
:
methods:{
...mapMutations({'add':'JIA','jian':'JIAN'})
}
然后就出现了错误
store > index.js
//准备mutations:用于操作数据(state)
const mutations = {
JIA(state,value){
//它带过来的值到底是多少
console.log('@@@@@@', value)
state.sum += value
},
JIAN(state,value){
state.sum -= value
},
}
PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
借助配置项 生成一个add
方法
我们自己写的add方法:
add(){
this.$store.commit('JIA',this.n)
}
但是生成的add方法:
add(value){
this.$store.commit('JIA',value)
}
所以它不知道要加的是在哪里
怎么解决?
<button @click="add(n)">+</button>
<button @click="jf(n)">-</button>
数组写法(只能写mutations里的名字):
...mapMutations(['JIA','JIAN'])
所以生成的方法是JIA()
Vuex集中式管理中没有dispatch
而是mapActions
<template>
<div>
<h3>当前求和:{{sum}}</h3>
<h4>当前求和的值放大10倍:{{$store.getters.bigSum}}</h4>
<h4>我在{{school}},学习{{subject}}</h4>
<select name="" id="" v-model.number="n">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button @click="add(n)">+</button>
<button @click="jf(n)">-</button>
<button @click="jadd(n)">当前求和为奇数再加</button>
<button @click="delayAdd(n)">等一等再加</button>
</div>
</template>
<script>
import {mapState,mapGetters,mapMutations,mapActions} from 'vuex'
export default {
name: 'Add',
components:{},
data() {
return {
n:1,
}
},
methods: {
...mapMutations({add:'JIA',jf:'JIAN'}),
...mapActions(['jadd','delayAdd'])
},
}
</script>
mapActions与mapMutations使用时,若需要传递参数需要:再模板中绑定事件时传递好参数,否则参数是事件对象。