Vue 状态管理模式 -- Vuex

这是我参与更文挑战的第4天,活动详情查看: 更文挑战vue

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化ios

本章讲解 Vue 项目中 Vuex 的具体使用vuex

先在项目目录下创建一个 store 文件夹,而且在下面创建一个 index.js 文件axios

image.png

// index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
复制代码

在 Vue 实例上挂载 store数组

// main.js
import store from '@/store'

new Vue({
  el: '#app',
  store
})
复制代码

在全局去使用store,在组件里就能够经过 this.$store.state.data 全局调用缓存

建立 modules

当应用比较很是复杂时,Vuex 容许咱们将 store 分割成模块(module)。每一个模块拥有本身的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行一样方式的分割markdown

例:modules / user 模块app

image.png

每一个状态集最后合成到index.js中异步

image.png

模块中的 state、getters、mutations、actionsasync

state

const state = {
  pool_list_data: '',
  pool_id_list: [],
  current_pools: {
    poolId: "CIDC-RP-25",
    poolName: "华东-苏州",
  },
}

this.$store.state.user.pool_list_data
复制代码

经过 store.state 来获取状态对象,以及经过 store.commit 方法触发状态变动

Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地获得高效更新

不能直接改变 store 中的状态。改变 store 中的状态的惟一途径就是显式地提交 (commit) mutation。这样使得咱们能够方便地跟踪每个状态的变化,从而让咱们可以实现一些工具帮助咱们更好地了解咱们的应用

因为 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅须要在计算属性中返回便可。触发变化也仅仅是在组件的 methods 中提交 mutation

getters

const getters = {
  doneTodos: state => {
    return state.todos.filter(todo => todo.done)
  }
  pool_list_data: state => state.pool_list_data,
  pool_id_list: state => state.pool_id_list,
  current_pools: state => state.current_pools,
}

store.getters["user/doneTodos"]
复制代码

getter能够认为是 store 的计算属性,就像计算属性同样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被从新计算

也能够经过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时很是有用

注意:getter 在经过方法访问时,每次都会去进行调用,而不会缓存结果

mapGetters

mport { mapGetters } from 'vuex'

export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // 使用对象形式,能够给 getter 属性另取一个名字
      // doneCount: 'doneTodosCount'
    ])
  }
}
复制代码

mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性

mutations

更改 Vuex 的 store 中的状态的惟一方法是提交 mutation。Vuex 中的 mutation 很是相似于事件:每一个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是咱们实际进行状态更改的地方,而且它会接受 state 做为第一个参数

你能够向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)

const mutations = {
  'SET_POOL_INFO'(state, pooldata) {
    state.pool_list_data = pooldata
    state.pool_id_list = []
    pooldata.forEach((i) => {
      state.pool_id_list.push(i.poolId)
    })
  },
  'SET_CURRENT_POOLS'(state, region_data) {
    state.current_pools.poolId = region_data.value
    state.current_pools.poolName = region_data.name
  }
}

commit('SET_CURRENT_POOLS', region_data)
复制代码

actions

Action 相似于 mutation,不一样在于:

  • Action 提交的是 mutation,而不是直接变动状态
  • Action 能够包含任意异步操做
const actions = {
  async getInfo({ commit }) {
    return new Promise(async (resolve, reject) => {
      commit('SET_ROLES', ['Admin'])
      axios.defaults.headers.common["pool-Id"] = state.current_pools.poolId
      const user = await getUserInfo({ user_id: state.user_id })
      if (user.status == 200) {
        commit('SET_ECLOUD_USER', user.data)
      }
      resolve(state.roles)
    })
  },
}

// Action 经过 store.dispatch 方法触发,一样支持载荷方式和对象方式进行分发
this.$store.dispatch('user/getInfo')
复制代码

mapActions

在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用

mport { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'user/getInfo', 
      // 将 this.increment() 映射为 this.$store.dispatch('user/getInfo')
      // mapActions 也支持载荷,及对象形式
    ]),
  }
}
复制代码