Skip to content

Vuex

Vuex 是 Vue.js 的一个状态管理模式和库,用于集中式管理应用的状态。它适用于中大型应用程序,在这些应用中,多个组件之间需要共享状态。Vuex 的核心思想是通过一个全局的、响应式的状态树来管理应用的状态。

Vuex 的核心概念

  1. State(状态)

    • State 是存储应用状态的地方。在 Vuex 中,状态存储是响应式的,意味着当你从 store 中读取状态时,任何组件都会自动更新以反映状态的变化。
  2. Getters(获取器)

    • Getters 类似于 Vue 中的计算属性。它们用于从 store 中派生出一些状态。Getters 可以用于过滤、计算或格式化状态数据。
  3. Mutations(变更)

    • Mutations 是唯一能够更改 Vuex 状态的方式。每个 mutation 都有一个字符串的事件类型和一个回调函数。回调函数接收 state 作为第一个参数,payload 作为第二个参数。
  4. Actions(动作)

    • Actions 类似于 mutations,但有以下不同:
      • Action 提交的是 mutation,而不是直接变更状态。
      • Action 可以包含任意异步操作。
  5. Modules(模块)

    • 当应用变得非常复杂时,可以将 store 分割成模块。每个模块拥有自己的 state、mutations、actions 和 getters,甚至可以嵌套子模块。

使用 Vuex 的步骤

  1. 安装 Vuex

    • 如果使用 Vue CLI 创建项目,Vuex 通常会自动安装。如果没有,可以通过 npm 或 yarn 安装:
      bash
      npm install vuex --save
  2. 创建 Store

    • 创建一个新的 Vuex.Store 实例,并在其中定义 state、mutations、actions 和 getters。

      javascript
      import Vue from 'vue'
      import Vuex from 'vuex'
      
      Vue.use(Vuex)
      
      const store = new Vuex.Store({
        state: {
          count: 0
        },
        mutations: {
          increment(state) {
            state.count++
          }
        },
        actions: {
          incrementAsync({ commit }) {
            setTimeout(() => {
              commit('increment')
            }, 1000)
          }
        },
        getters: {
          doubleCount(state) {
            return state.count * 2
          }
        }
      })
      
      export default store
  3. 在 Vue 实例中使用 Store

    • 在 Vue 实例中注册 store。
      javascript
      new Vue({
        el: '#app',
        store,
        render: (h) => h(App)
      })
  4. 在组件中访问 Store

    • 可以通过 this.$store.state 访问状态,通过 this.$store.commit 提交 mutations,通过 this.$store.dispatch 分发 actions。
    • 使用 mapStatemapGettersmapMutationsmapActions 辅助函数来简化代码。

Vuex 提供了一种结构化的方式来管理应用的状态,使得状态管理更为清晰和可维护。对于复杂的应用程序,使用 Vuex 可以显著提高代码的组织性和可读性。

辅助函数

在 Vuex 中,mapStatemapGettersmapMutationsmapActions 是四个常用的辅助函数,它们可以帮助我们更方便地在组件中使用 Vuex 的状态、获取器、变更和动作。下面是每个辅助函数的使用示例:

1. mapState

mapState 用于将 store 中的 state 映射到组件的计算属性中。

javascript
import { mapState } from 'vuex'

export default {
  computed: {
    // 使用对象展开运算符将 mapState 返回的对象混入到 this 上
    ...mapState({
      count: (state) => state.count, // 将 state.count 映射为 this.count
      anotherState: (state) => state.anotherState // 其他状态映射
    })
  }
}

或者使用更简单的数组语法:

javascript
export default {
  computed: {
    ...mapState([
      'count' // 将 state.count 映射为 this.count
    ])
  }
}

2. mapGetters

mapGetters 用于将 store 中的 getters 映射到组件的计算属性中。

javascript
import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters([
      'doubleCount' // 将 getter doubleCount 映射为 this.doubleCount
    ])
  }
}

3. mapMutations

mapMutations 用于将 store 中的 mutations 映射到组件的方法中。

javascript
import { mapMutations } from 'vuex'

export default {
  methods: {
    ...mapMutations([
      'increment' // 将 mutation increment 映射为 this.increment
    ]),
    ...mapMutations({
      add: 'increment' // 将 mutation increment 映射为 this.add
    })
  }
}

4. mapActions

mapActions 用于将 store 中的 actions 映射到组件的方法中。

javascript
import { mapActions } from 'vuex'

export default {
  methods: {
    ...mapActions([
      'incrementAsync' // 将 action incrementAsync 映射为 this.incrementAsync
    ]),
    ...mapActions({
      asyncAdd: 'incrementAsync' // 将 action incrementAsync 映射为 this.asyncAdd
    })
  }
}

使用示例

假设我们有一个简单的 Vuex store:

javascript
const store = new Vuex.Store({
  state: {
    count: 0
  },
  getters: {
    doubleCount: (state) => state.count * 2
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment')
      }, 1000)
    }
  }
})

在组件中,我们可以使用上述的 map 辅助函数来访问和操作 Vuex 的状态:

javascript
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
    <button @click="incrementAsync">Increment Async</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['doubleCount'])
  },
  methods: {
    ...mapMutations(['increment']),
    ...mapActions(['incrementAsync'])
  }
}
</script>

这样写可以使代码更加简洁和易于维护,特别是在需要访问多个 state、getters、mutations 或 actions 时。

hancenter808@outlook.com