Vuex

118 阅读4分钟

Vuex

  • 注意: vue2安装3的版本 (npm i vuex@3)
  • Vuex是一个专为Vue.js应用程序开发的状态管理模式。它可以用于集中管理和共享应用程序的所有组件之间的状态数据。Vuex的目标是使状态管理简单且可预测。
  • 在Vue.js应用程序中,组件之间的状态共享通常需要通过父子组件传递props或通过事件进行通信。但随着应用程序的复杂性增加,这种方式变得繁琐且难以维护。Vuex提供了一个集中式的状态管理架构,将应用程序的所有组件的状态集中管理。

Vuex的核心概念包括:

  1. State(状态):用于存储应用程序的状态数据,可以通过this.$store.state访问。
  2. Getters(计算属性):用于从状态中派生出新的状态,类似于组件中的计算属性,可以通过this.$store.getters访问。
  3. Mutations(突变):用于修改状态,必须是同步函数,通过commit方法调用,可以通过this.$store.commit访问。
  4. Actions(动作):类似于突变,但可以包含异步操作,可以通过dispatch方法调用,可以通过this.$store.dispatch访问。
  5. Modules(模块):用于将Vuex状态划分为模块,每个模块都有自己的state、getters、mutations和actions。
  • 通过使用Vuex,你可以在任何组件中轻松访问和修改应用程序的状态,而无需通过组件之间的传递和事件通信来进行状态管理。Vuex提供了一个中央存储库(store)来集中管理状态,使状态的变化更加可追踪和可控。
  • 要使用Vuex,你需要在Vue.js应用程序中进行安装和配置。你可以通过npm安装Vuex,并将其配置为Vue应用程序的插件。然后,在根组件中创建一个Vuex store,并将其传递给Vue实例,这样整个应用程序中的所有组件都可以访问该store。

示例:

  • 当使用Vuex进行组件间通讯时,以下是一个简化的示例:
  • 首先,假设我们有两个组件:ComponentA和ComponentB。我们希望在这两个组件之间共享一个消息。
  • 在Vuex中,我们需要做以下几个步骤:
  1. 安装和配置Vuex。在你的项目中安装Vuex,并创建一个名为store.js的文件,包含以下内容:
// store.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: 'Hello from Vuex!', // 初始消息
  },
  mutations: {
    updateMessage(state, newMessage) {
      state.message = newMessage; // 更新消息
    },
  },
})
  1. 在根组件中导入并配置Vuex store。
// main.js

import Vue from 'vue';
import App from './App.vue';
import store from './store'; // 导入Vuex store

new Vue({
  store, // 将Vuex store应用到Vue实例中
  render: (h) => h(App),
}).$mount('#app');
  1. 在ComponentA中,我们从Vuex store获取消息并允许用户更新它。
<template>
  <div>
    <h2>Component A</h2>
    <p>{{ message }}</p> <!-- 显示从Vuex获取的消息 -->
    <input type="text" v-model="newMessage" /> <!-- 输入新消息 -->
    <button @click="updateMessage">Update Message</button> <!-- 点击按钮更新消息 -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      newMessage: '', // 用于存储输入的新消息
    };
  },
  computed: {
    message() {
      return this.$store.state.message; // 从Vuex获取消息
    },
  },
  methods: {
    updateMessage() {
      this.$store.commit('updateMessage', this.newMessage); // 更新消息到Vuex
    },
  },
};
</script>
  1. 在ComponentB中,我们从Vuex store获取相同的消息并显示它。
<template>
  <div>
    <h2>Component B</h2>
    <p>{{ message }}</p> <!-- 显示从Vuex获取的消息 -->
  </div>
</template>

<script>
export default {
  computed: {
    message() {
      return this.$store.state.message; // 从Vuex获取消息
    },
  },
};
</script>

现在,当用户在ComponentA中更新消息时,ComponentB将自动显示更新后的消息。这是通过Vuex实现的组件间通信。

使用Modules分割多个模块的方式

  1. 使用registerModule方法
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store()
const moduleA = {
  state: {
    msg: 'a'
  },
  mutations: {},
  getters: {},
  actions: {}
}

const moduleB = {
  state: {
    msg: 'b'
  },
  mutations: {},
  getters: {},
  actions: {}
}

store.registerModule('moduleA', moduleA)
store.registerModule('moduleB', moduleB)
  1. modules选项
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
  modules: {
    moduleA: {
      state: {
        msg: 'a'
      },
      mutations: {},
      getters: {},
      actions: {}
    },
    moduleB: {
      state: {
        msg: 'b'
      },
      mutations: {},
      getters: {},
      actions: {}
    }
  }
})
  1. 可以将一个模块的状态、mutations、getters 和 actions 分别写在一个单独的文件中,然后通过 import 导入并注册到 Vuex 的 store 实例中。
// moduleA.js 
   export default { state: { ... }, mutations: { ... }, getters: { ... }, actions: { ... } }

// moduleB.js 
   export default { state: { ... }, mutations: { ... }, getters: { ... }, actions: { ... } }

// store.js 
   import moduleA from './moduleA' 
   import moduleB from './moduleB'

   const store = new Vuex.Store({ modules: { moduleA, moduleB, } })
  • 上面使用都是一样的this.$store.state.moduleAthis.$store.state.moduleB

vuex-辅助函数

  • 当使用 Vuex 辅助函数时,可以通过添加注释来更好地理解每个辅助函数的作用。以下是给这5个辅助函数添加注释的示例代码:
  1. mapState 辅助函数示例:
import { mapState } from 'vuex';

export default {
  computed: {
    // 将 count 状态映射到组件的计算属性中
    ...mapState({
      count: (state) => state.counter.count,
    }),
  },
};

  1. mapGetters 辅助函数示例:
import { mapGetters } from 'vuex';

export default {
  computed: {
    // 将 formattedMessage getter 映射到组件的计算属性中
    ...mapGetters(['formattedMessage']),
  },
};

  1. mapMutations 辅助函数示例:
import { mapMutations } from 'vuex';

export default {
  methods: {
    // 将 increment mutation 映射到组件的方法中
    ...mapMutations(['increment']),
  },
};
  1. mapActions 辅助函数示例:
import { mapActions } from 'vuex';

export default {
  methods: {
    // 将 fetchData action 映射到组件的方法中
    ...mapActions(['fetchData']),
  },
};

注意:

  • 如果你的 Vuex 应用进行了模块化,你可以在使用辅助函数时指定命名空间来访问模块中的状态、getter、mutation和action。以下是一个示例代码:
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';

export default {
  computed: {
    ...mapState('moduleName', {
      count: (state) => state.count,
    }),
    ...mapGetters('moduleName', ['formattedMessage']),
  },
  methods: {
    ...mapMutations('moduleName', ['increment']),
    ...mapActions('moduleName', ['fetchData']),
  },
};
  • 在上述示例中,我们使用辅助函数来访问名为 'moduleName' 的 Vuex 模块。通过在辅助函数中指定模块名称作为第一个参数,可以访问该模块中的状态、getter、mutation和action。
  • 请注意,mapStatemapGettersmapMutationsmapActions 都可以接收一个字符串参数,用于指定模块名称,后面紧跟对象或数组参数,用于指定要映射的状态、getter、mutation或action。