如何模块化使用 Vuex?

165 阅读2分钟

 不使用模块化

正常情况下,如果系统不是特别复杂,而我们又需要用到 Vuex 进行全局状态管理,那这种情况下是不需要模块化使用 Vuex 的,写到一个文件下即可,代码如下所示:

// src/store/index.js

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

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0, // 一个简单的状态示例
  },
  mutations: {
    increment(state) {
      state.count++;
    },
    decrement(state) {
      state.count--;
    },
  },
  actions: {
    increment(context) {
      context.commit('increment');
    },
    decrement(context) {
      context.commit('decrement');
    },
  },
  getters: {
    getCount: state => state.count,
  },
});

在组件中使用 Vuex: 在页面中使用也相对简单,代码如下,可以借助 map 函数解析展开使用。

// src/components/Counter.vue

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
    <button @click="decrement">Decrement</button>
  </div>
</template>

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

export default {
  computed: {
    ...mapState(['count']),
  },
  methods: {
    ...mapActions(['increment', 'decrement']),
  },
};
</script>

使用模块化

在个人小项目当中,不使用模块化没什么问题。

但是在公司里面比如你和你的同事负责了十几个模块,那如果把所有模块还是写到一个文件里是不合适的,代码会非常多,非常乱,这个时候就适合模块化了。

使用模块化有利于可维护性、团队协作、代码结构清晰、提高可读性等优点。

现在假设你有两个模块,一个用于管理用户信息,另一个用于管理商品信息。

首先,分别创建两个 Vuex 模块文件:

模块文件

userModule.js

    // userModule.js
    const state = {
      user: null,
      userName:"张三"
    };

    const mutations = {
      SET_USER(state, user) {
        state.user = user;
      },
    };

    const actions = {
      setUser({ commit }, user) {
        commit("SET_USER", user);
      },
    };

    export default {
      namespaced: true,
      state,
      mutations,
      actions,
    };

productModule.js

    // productModule.js
    const state = {
      products: [],
      productName:'电脑'
    };

    const mutations = {
      ADD_PRODUCT(state, product) {
        state.products.push(product);
      },
    };

    const actions = {
      addProduct({ commit }, product) {
        commit("ADD_PRODUCT", product);
      },
    };

    export default {
      namespaced: true,
      state,
      mutations,
      actions,
    };

把模块中用到的 state 数据集中模块的状态到 Getters,方便页面中使用

在根级 Vuex Store 中创建 Getters,用于集中所有模块的状态数据:

getters.js

    // getters.js
    export default {
      userName: state => state.user.userName,
      productName: state => state.product.productName,
    };

最后创建根级的 Vuex Store 文件,将上述的模块引入并注册:

store.js

    import Vue from 'vue';
    import Vuex from 'vuex';
    import userModule from './userModule';
    import productModule from './productModule';
    import getters from './getters'; // 导入 getters 为对象

    Vue.use(Vuex);

    const store = new Vuex.Store({
      modules: {
        user: userModule,
        product: productModule,
      },
      getters,
    });

    export default store;

页面使用

如果使用模块中 state 中的数据,前面我们已经集中放到了getters里面,直接取即可。

其他使用 mutatio n或者 action 的函数和不使用模块化类似,只需要在前面加上模块名称即可。

    <template>
      <div>
        <h1>User Name: {{ userName }}</h1>
      </div>
    </template>

    <script>
    export default {
      computed: {
        userName() {
          return this.$store.getters.userName;
        }
      },
      mounted() {
        this.$store.dispatch("user/setUser", { userName: "John Doe" });
        this.$store.dispatch("product/addProduct", { name: "Product A" });
      },
    };
    </script>

如果没有放到getters里面,就需要取的时候额外加上模块名称即可。

this.$store.state.user.userName;