状态管理
打算开发中大型应用,集中式数据管理, 一处修改,多处使用,多个组件依赖于同一状态,来自不同组件的行为需要变更同一状态,生态环境给我们提供了官方插件vuex
vuex相关成员
import Vuex from 'vuex'
, Vuex是个对象,相关成员如下
成员 | 用途 |
---|---|
Store | 类,构造状态管理的实例 |
mapActions | 函数,通讯工具,组件与Actions的通讯工具 |
mapMutations | 函数,通讯工具,组件与Mutations的通讯工具 |
mapGetters | 函数,通讯工具,组件与Getters的通讯工具 |
mapState | 函数,通讯工具,组件与State的通讯工具 |
状态管理实例相关成员
成员 | 用途 |
---|---|
dispatch | 实例方法,通讯工具,组件发请求到actions |
commit | 实例方法,通讯工具,组件发请求到actions,mutations。actions发请求到mutations |
state | 属性,获取公共数据,组件发请求到state |
角色分工
正常组件找某个属性count,找不到,会去计算属性内找
actions与mutations属于方法
state与getters属于计算属性
components-> | actions-> | mutations-> | state | <-getters-> | ->components |
---|---|---|---|---|---|
发送请求 | 处理业务,异步 | 修改状态 不负责做业务只负责数据的突变,控制state | 状态 | 读取处理状态 类似于计算属性与过滤器的功能 | 渲染状态 |
学生 | 代课老师 | 校长 | 财务 | 班主任 | 学生 |
dispatch | commit | state.key=value | {key:value} | state.key | {{key}} |
mapActions-> | <-mapGetters | ||||
mapMutations-> | -------------------> | <------------ | <-mapState | ||
commit-> | -------------------> | ||||
<------------ | <-state |
1.
commit 可以被components的组件作为工具直接访问actions与mutations里面的方法
2.组件对于actions与mutations的请求方式
mapActions 可以完全代替methods里面的方法。具体写法如下
methods: {
1 jia (num) {
2 this.$store.dispatch('jia',num)
3 },
}
这个是用了store所带的相关成员。可以用vuex的实例成员取代
methods:mapActions(["jia","jian","odd","yibu"])
上述的这行代码mapActions(["jia","jian","odd","yibu"]),完全等于1.2.3行代码加上花括号,如果在methods{}里面写,则可以如下写:
methods: {
// jia (num) {
// this.$store.dispatch('jia',num)
// },
// increment (num) {
// this.$store.commit('increment',num)
// },
...mapActions(["jia","jian","odd","yibu"]),
...mapMutations(["increment","decrement"])
},
3.组件对于count与getters的请求方式
computed:{
// getCount () {
// return this.$store.getters.getCount +1
// },
// count () {
// return this.$store.state.count +1
// },
...mapState(["count"]),
...mapGetters(['getCount']),
},
4.actions书写方式实例
import axios from 'axios';
let actions = {
// 类型:处理函数(context,payload) 上下文{distpath,commit,state,getters},负载
/* jia:(ctx,payload)=>{
// console.log('actions',ctx,payload);
// ctx.commit('类型',负载)
ctx.commit('increment',payload)
} */
jia:({commit},payload)=>{
console.log('actions');
commit('increment',payload)
// state.count+=100
},
jian:({commit},payload)=>{
console.log('actions',payload);
commit('decrement',payload)
},
odd:({commit,state},payload)=>{
if(state.count % 2 === 0){
commit('increment',payload)
}
},
yibu:({commit},payload)=>{
//异步动作,根据结果,提交给mutations
axios({
url:'/data/product1.json'
}).then(
res=>commit('increment',res.data[0].price)
)
}
};
export default actions;
5.mutations书写实例
let mutations = {
increment(state, payload) {//state == state.js
// console.log('mutations', state, payload);
console.log('mutations');
state.count += payload
},
decrement(state,payload){
console.log('mutations');
state.count -= payload
}
};
export default mutations;
6.state书写实例
let state = {
count:0
};
export default state;
7.getters书写实例
let getters = {
getCount:(state,getters)=>{
// console.log('getters',state,getters);//state == state.js getters == this
return '处理后后的' + state.count
},
};
export default getters;
交互流程图
配置
// /src/main.js
//引入store实例
import store from './plugins/vuex.js'
new Vue({
render: h => h(App),
store//控制vue实例,为vue实例提供一个状态管理实例,管理整个vue公共状态
}).$mount('#app')
// src/plugins/vuex.js
//配置 store
import Vue from 'vue';
import Vuex from 'vuex';//引入vuex包
Vue.use(Vuex);//安装插件到vue
import state from '../store/state.js'
import actions from '../store/actions.js'
import mutations from '../store/mutations.js'
import getters from '../store/getters.js'
let store = new Vuex.Store({//配置接受state等选项,值为对象
state,mutations,
getters,actions
});
export default store;//导出store实例给main.js
// src/store/state.js
let state={
count:0
}
export default state;
// src/store/actions
let actions = {
jia:({commit,state},payload)=>{
//第一个选项上下文content,state 公共状态 payload 负载
commit('increment',payload)
}
};
export default actions;
// src/store/mutations.js
let mutations={
increment:(state,payload)=>{
//state 仓库|公共数据 payload携带的负载
state.count+=payload;//mutations 不做业务,只负责突变state
}
};
export default mutations;
// src/store/getters.js
let getters = {
count:(state)=>{
//返回处理后的state ~~ computed
return state.count % 2 === 0 ? state.count + '偶数': state.count + '奇数'
}
};
export default getters;
组件中使用
<!--声明式 发送请求-->
<div @click="类型(负载)"></div>
<!--展示状态-->
<div>{{count}}</div>
<div>{{$store.state.count}}</div>
import {mapActions, mapMutations,mapState,mapGetters} from 'vuex'
import store from './plugins/vuex.js';
export default {
name: 'app',
methods:{
jia(){
//编程式 发送请求
store | this.$store.commit('类型',数据/负载/payload) //-> mutations
store | this.$store.dispatch('类型',数据/负载/payload) //-> actions
store | this.$store.dispatch|commit({type:'类型',payload:负载})
}
},
//上述的methods可以用下述的这个方法来代替
//mapActions 用来接管methods,返回一个对象
methods:mapActions([
'jia'
])
//mapMutations 接管methods,跳过actions找mutations
methods:mapMutations([
'increment'
])
methods:{
...mapMutations([//mapMutations 返回来一个对象
'increment'
]),
...mapActions(['jia']),//mapActions 返回来一个对象
show(){//组件内部methods
...
}
},
//mapGetters接管computed,返回一个对象
computed:mapGetters([
'count'
]),
computed:mapState([
'count'
]),
computed:{
...mapState([//mapState返回一个对象
'count'
]),
...mapGetters([
'count'
])
count(){ //组件内容计算属性
return this.$store.state.count % 2 === 0 ?
this.$store.state.count + '偶数' :
this.$store.state.count + '奇数'
}
}
}
vuex融入到项目当中
创建types:收藏vuex提交类型,便于后期修改,和一些types工具检查
路由监听:找一个不会被卸载组件,做数据观测(属性检测 watch),commit
到mutations
突变state.nav数据
拦截器:请求和响应前后,commit
->mutations
突变state.bLoading