vuex
一、 State
Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。 这段话说的是一个 Vuex 只能包含一个 store(存储数据的库),这样你在访问数据的时候好找些。
state
类似 vue 实例中的 data
选项,就是把数据放在这里面。
vuex 中的数据源,我们需要保存的数据就保存在这里,可以在页面通过 this.$store.state
来获取我们定义的数据
实例
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// 是否打开播放器
openplayer: false,
//播放状态
audiostate: false,
//当前播放列表
curplayList: [],
//当前歌曲在列表中的index
curindex: -1
}
});
获取 state
this.$store.state.curplayList;
// 或
computed: mapState([
// 映射 this.curplayList store.state.curplayList
"curplayList"
]);
二、 Getter
Getter 相当于 vue 中的 computed 计算属性,getter
的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算,这里我们可以通过定义 vuex 的 Getter 来获取,Getters 可以用于监听、state
中的值的变化,返回计算后的结果.
格式化、过滤数据时也可以用 getter
实例
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// 是否打开播放器
openplayer: false,
//播放状态
audiostate: false,
//当前播放列表
curplayList: [],
//当前歌曲在列表中的index
curindex: -1
},
getters: {
//监听播放歌曲的下标
playdetails: state => {
return state.curplayList.length > 0 && state.curplayList[state.curindex];
}
// ---------1. 过滤歌手信息,当前歌曲有多个歌手的处理
// songListFormat: (state) => {
// state.curplayList.forEach(song => {
// let str = '';
// song.ar.forEach((ar, index) => {
// if (index != 0) {
// }
// })
// })
// }
//----------- 2. 获取id为465的歌
// song456(state){
// return state.curplayList.find((el)=>{
// return el.id == 456;
// });
// }
}
});
获取 getters
this.$store.getters.playdetails;
三、 Mutation
更改 Vuex 的 store
中的状态的唯一方法是提交 mutation
。Vuex 中的 mutation
非常类似于事件:每个 mutation
都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state
作为第一个参数:
实例
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// 是否打开播放器
openplayer: false,
//播放状态
audiostate: false,
//当前播放列表
curplayList: [],
//当前歌曲在列表中的index
curindex: -1
},
mutations: {
// 歌曲的播放状态
audioState(state, val) {
state.audiostate = val;
},
//当前播放列表
curPlayList(state, val) {
state.curplayList = val;
}
}
});
调用 mutations
// 通过mutations把数据保存到state
let myMusicList = [];
this.$store.commit("curPlayList", myMusicList);
!> 在 Vuex 中,mutation
都是同步事务
四、 Action
Action 类似于 mutation,不同在于:
Action
提交的是mutation
,而不是直接变更状态。Action
可以包含任意异步操作。
也就是说,Action 执行的还是 Mutation ,只不过他可以异步执行,差不多就是给 Mutation 外边包了一层函数。
Action 函数接受一个与 store
实例具有相同方法和属性的 context
对象,因此你可以调用 context.commit
提交一个 mutation
,或者通过 context.state
和 context.getters
来获取 state
和 getters
。
实例
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
// 是否打开播放器
openplayer: false,
//播放状态
audiostate: false,
//当前播放列表
curplayList: [],
//当前歌曲在列表中的index
curindex: -1,
//歌曲详情
songinfoDetails: null
},
mutations: {
// 歌曲的播放状态
audioState(state, val) {
state.audiostate = val;
},
//当前播放列表
curPlayList(state, val) {
state.curplayList = val;
},
//歌曲详情
songInfoDetails(state, val) {
state.songinfoDetails = val;
}
},
actions: {
getSongdetails(context, id) {
let songdetail = {
url: "/song/detail",
method: "get",
//此处传入歌曲ids
params: {
ids: id
}
};
getSource(songdetail).then(res => {
console.log("songdetail", res);
context.commit("songInfoDetails", res.data.songs[0]);
});
}
}
});
触发 actions
Action 通过 store.dispatch
方法触发:
this.$store.dispatch('getSongdetails')
五、 Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store
分割成模块(module)。每个模块拥有自己的 state
、mutation
、action
、getter
、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态