vuex

vuex 官方文档open in new window

一、 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.statecontext.getters 来获取 stategetters

实例

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)。每个模块拥有自己的 statemutationactiongetter 、甚至是嵌套子模块——从上至下进行同样方式的分割:

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 的状态
Last Updated:
Contributors: zerojs