State使用
// store/index.js
state: {
buttonPermissions:{
add:true,
edit:false
}
},
//某个页面使用
created() {
console.log("this.$store",this.$store.state)
},
由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性 (opens new window)中返回某个状态
mapState辅助函数
``mapState 辅助函数返回的是一个对象
一个vuex属性都是写在 计算属性 中 , 但是很显然 直接下边这样写就定义不了其他的计算属性了
基本使用
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount //this.localCount当前组件的数据
}
- 通过箭头函数
- 通过字符串
- 通过常规函数
页面整体使用
//页面使用
<template>
<div>
<h2><span>使用:</span> {{$store.state}}</h2>
<h2><span>data中的count:</span>{{count}}</h2>
<h2><span>辅助函数Count:</span>{{handleCount}}</h2>
<h2><span>辅助函数countAlias:</span>{{countAlias}}</h2>
<h2><span>辅助函数countPlusLocalState:</span>{{countPlusLocalState}}</h2>
<h2><span>辅助函数power:</span>{{power}}</h2>
</div>
</template>
<script>
import {mapState } from "vuex";
export default {
data () {
return {
count:this.$store.state.count,
localCount:"局部状态"
}
},
computed:mapState({
// 箭头函数可使代码更简练
handleCount: state => state.count,
// // 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// // 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
},
power:"buttonPermissions"
}),
components: {},
methods: {
hadnleChangeState(){
console.log("this.$store",this.$store);
}
}
}
</script>
<style scoped>
</style>
当我们计算属性的名称与state的子节点 相同, 我们也可以传一个数组
// store/index.js
export default new Vuex.Store({
state: {
buttonPermissions:{
add:true,
edit:false
},
count:1
},
})
//某页面
computed:mapState(["count","buttonPermissions"])
解构使用
因为辅助函数返回的是一个对象,所以我们就可以使用扩展运算符,这样就可以和局部的计算属性混合使用了
Getters使用
参数说明:
- 接收
state为第一个参数 - 接受其他
getter作为第二个参数
基本使用 — 以及第二参数使用 — 通过返回一个方法 对getter传参
//某个页面
<template>
<div>
<h2><span></span>{{$store.getters}}</h2>
<h2><span>第二参数的使用:</span>{{$store.getters.clickCount}}</h2>
<h2><span>返回一个函数:</span>{{$store.getters.find("媒体查询响应式布局")}}</h2>
</div>
</template>
// @/store/index.js
state: {
lessons:[
{ title: "媒体查询响应式布局", click: 10 },
{ title: "FLEX 弹性盒模型", click: 20 },
{ title: "MYSQL多表查询随意操作", click: 100 }
],
}
getters:{
//基本使用
total :state => state.lessons.reduce((pre,cur) => pre + cur.click,0),
//第二参数使用
clickCount:(state,getters) => "点了量为:"+getters.total
//通过返回一个方法 对getter传参
find:(state) => (title) => state.lessons.find(item => item.title == title)
},
mapGetters辅助函数
//某个vue页面
<h2><span>mapGetters辅助函数</span>{{total}}</h2>
<h2><span>mapGetters辅助函数</span>{{clickCount}}</h2>
<h2><span>mapGetters辅助函数</span>{{find("MYSQL多表查询随意操作")}}</h2>
computed:{
...mapGetters(["total","clickCount","find"]);//数组方式
...mapGetters({ //对象方式
astotal:"total",
click:"clickCount",
fn:"find"
})
}
- mapGetters 只有
数组和对象的方式 进行映射到计算属性 - 使用数组方式是为了别名
Mutations使用
更改state 唯一办法就是 使用mutaion 方式提交
Mutation参数说明:
- 接收
state为第一个参数 - 接收
commit的第二参数
不能直接this.$store.mutation调用,需要调用store中的commit方法
commit()方法参数说明
-
commit()方法 只有
两个参数 -
mutations 属字符串作为为第一参数 -
第二参数(官方称之为载荷) 可以 传递 任意值, 一般传obj
基本使用 - 提交载荷 - 对象方式提交载荷
//某个vue页面
<h2><span>count:</span>{{$store.state.count}}</h2>
<button @click="handleClick">mutations调用</button>
<button @click="handleClickSub">载荷调用</button>
<button @click="handleClickSubObj">对象方式载荷调用</button>
methods: {
//基本使用
handleClick(){
this.$store.commit("increment")
},
//提交载荷
handleClickSub(){
this.$store.commit('sub',{num:10})
}
//对象方式提交载荷 handler保持不变
handleClickSubObj(){
this.$store.commit({type:'sub',num:10})
}
}
// @/store/index.js
state: {
count:1,
},
//基本使用
increment(state){
state.count++
}
//提交载荷
sub(state,data){
state.count -= data.num
}
Mutation需遵守Vue的响应规则
- 提前在store中初始化所有所需属性
- 当需要在对象
添加新属性时,应该- 使用Vue.set(obj,"key",123),或者
- 使用扩展运算符 新对象 替换老对象
- {...state.obj , newProp:123}
Mutation必须是同步的
mapMutation辅助函数
methods: {
handleClick(){
this.increment();
},
handleClickSub(){
this.sub({num:10})
},
handleClickSubObj(){
this.sub({num:10})
},
...mapMutations([
"increment","sub"
])
}
Actions使用
Action 类似于 mutation,不同在于:
- Action
提交的是 mutation,而不是直接变更状态 - Action 可以包含任意异步操作
参数说明
- 函数接收一个与
store实例有相同方法和属性的context 对象,但是context对象不是store实例本身 - 所以我们可以通过context获取
- 提交mutation
- state
- getters
通过dispatch()方法触发
**基本使用 - 提交载荷 - 对象方式提交载荷 **
//某个 vue 组件
<h2><span>count:</span>{{$store.state.count}}</h2>
<button @click="handleClick">基本使用</button>
<button @click="handleClickSub">提交载荷</button>
methods: {
handleClick(){
this.$store.dispatch("increment")
},
handleClickSub(){
//提交载荷
this.$store.dispatch("sub",{num:10})
//对象方式提交载荷
this.$store.dispatch({type:"sub",num:10})
}
// @/store/index.js
state: {
count:1,
},
mutations: {
increment(state){
state.count++
},
sub(state,data){
state.count -= data.num
}
},
actions: {
increment({commit}){
setTimeout(() => {
commit("increment")
}, 2000);
},
sub({commit},obj){
setTimeout(() => {
commit("sub",obj)
}, 1000);
}
},
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')`
})
}
}
我们可以在使用async await 来控制action什么时候结束
Modules
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
//
this.$store.state.a // -> moduleA 的状态
this.$store.state.b // -> moduleB 的状态
总结
- State 作为存放 全局的状态
- Getters 可以视为 状态的计算属性,接收state为第一个参数,其他的getters 为第二个参数
- Mutations 是 用来 通过 commit()方法 直接修改 状态 State,commit()有两个参数,第一个为state,第二个是提交的载荷,一般是一个对象。 Muttaions 里边的方法必须是同步的。
- Actions 是通过dispatch()方法 来分发 Mutation 进而修改状态的 ,与Mutations不同的是它可以存放异步的方法,Actions方法里边的第一个参数 是接收一个 store 实例相同的对象,所以我们可以通过解构的方式获取我们想要的commit,state,getters,dsipatch 等