Vue核心组件Vuex

Vuex是类似redux 的一个概念,是一个专为 Vue.js 应用程序开发的状态管理模式. Vuex的核心概念包含 State,Getters,Mutations,Actions,Modules

State

保存一个单一的状态树

Getters

类似OOP中的魔法getter方法,可以访问一些State中没有的key ,或者覆盖一些Key的获取的方式; Getter 接受 state 作为其第一个参数

const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: '...', done: true },
      { id: 2, text: '...', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    },
	  getTodoById: (state) => (id) => {
    	return state.todos.find(todo => todo.id === id)
    }
  }
})

//访问方式 却和传统OOP不一样,必须显式声明getter
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }

//mapGetters 辅助函数
export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}

Mutations

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,mutation 必须是同步函数

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 变更状态
      state.count++
    }
  }
})

//调用方法 
store.commit('increment')

//传入额外的参数
//define
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
//call
store.commit('increment', {
  amount: 10
})
//对象风格的提交方式
store.commit({
  type: 'increment',
  amount: 10
})

Actions

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。 满足在提交mutation的时候做一些异步操作
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

//调用
//类似redux 的action 和 dispatch; 不同的是vuex增加了一个更基础的mutation操作
store.dispatch('increment')
// 以载荷形式分发
store.dispatch('incrementAsync', {
  amount: 10
})
// 以对象形式分发
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

Modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

const moduleA = {
  state: () => ({
    count: 0
  }),
  mutations: {
    increment (state) {
      // 这里的 `state` 对象是模块的局部状态
      state.count++
    }
  },

  getters: {
    doubleCount (state) {
      return state.count * 2
    },
	  // 模块内部的 getter,根节点状态会作为第三个参数暴露出来
	  sumWithRootCount (state, getters, rootState) {
      return state.count + rootState.count
    }

  },

	//对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState
	actions: {
    incrementIfOddOnRootSum ({ state, commit, rootState }) {
      if ((state.count + rootState.count) % 2 === 1) {
        commit('increment')
      }
    }
  }
}

const moduleB = {
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态