在官网中,介绍的虽然一针见血,但是可读性不是特别的强

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块

相对来说 本意就是 能够在大型项目中,更加细化的我们的状态管理,使得结构更加的清晰,当然,也会稍微有点儿复杂

先简单的举个例子

index.js 文件的内容

import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from '@/store/modules/moduleA'
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    name: 'xxx'
  },
  mutations: {
    changeName(state) {
      state.name = 'xxx+++';
    }
  },
  actions: {
  },
  // 就是使用modules属性在进行注册两个状态管理模块
  modules: {
    moduleA,
  }
});

export default store

moduleA.js的内容

export default {
  state: {
    name: 'aaa'
  },
  getters: {},
  mutations: {
    changeName(state, msg) {
      console.log(msg);
      state.name = 'aaa+++' + msg;
    }
  },
  actions: {
    actChangeName(context, msg) {
      console.log(msg);
      context.commit('changeName', msg);
    }
  }
}

调用state中数据的方式

由于我们是使用了模块化的方式,调用最外层的state中的数据 依然是this.$store.state.name

那么在使用modulesA中的方法的时候,是使用 this.$store.state.moduleA.name

调用mutations或者是actions中的方法

由于是没有对模块进行命名空间的,所以默认在使用 this.$store.commit/dispatch() 在提交方法的时候,会对所有状态管理的actions和mutations中的方法进行匹配,这就导致了一个问题,就是当不同模块之间的方法命名一样的情况下,会造成方法同时调用的问题

这个时候,我们需要在定义模块的时候,添加上 namespaced:true 属性

export default {
  namespaced: true, // 为当前模块开启独立的 命名空间
  state: {
    name: 'aaa'
  },
  getters: {},
  mutations: {
    changeName(state, msg) {
      console.log(msg);
      state.name = 'aaa+++' + msg;
    }
  },
  actions: {
    actChangeName(context, msg) {
      console.log(msg);
      context.commit('changeName', msg);
    }
  }
}

使用命名空间之后的调用方式

我们需要在使用 this.$store.commit/dispatch()  的时候 需要在前面加上我们当前模块名

例如: this.$store.commit("moduleA/changeName"); 

this.$store.dispatch("moduleA/actChangeName");

这样就可以去调用指定的模块里面的方法,当前最外围的mutations和actions还是一样的调用方式 

在使用了模块后属性的参数 

mutations和actions的参数是没什么太大变化的

getters中是这样的

 getters: {
    filters(state, getters, rootState) {
      console.log(getters); // 代表的是getters属性
      // rootState ---> 根节点的状态(也就是最外层的state)
      return state.name + rootState.name;
    }
  },

 

使用了模块化之后的辅助函数的使用

<!-- App -->
<template>
  <div id="app">
    <Panel>
      <template #test="{ user }">
        {{ user.id }}
      </template>
    </Panel>
    <h2>{{ name }}</h2>
    <button @click="changeName">触发mutations</button>
    <button @click="actChangeName">触发actions</button>
    <h2>{{ filters }}</h2>
  </div>
</template>

<script>
// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
// 例如:import 《组件名称》 from '《组件路径》';
import { createNamespacedHelpers } from "vuex";

const { mapState, mapMutations, mapActions, mapGetters } =
  createNamespacedHelpers("moduleA"); // 需要指定模块名字
import Panel from "@/components/Panel";
export default {
  name: "App",
  // import引入的组件需要注入到对象中才能使用
  components: {
    Panel,
  },
  data() {
    return {};
  },
  // 监听属性 类似于data概念
  computed: {
    ...mapState(["name"]),
    ...mapGetters(["filters"]),
  },
  // 监控data中的数据变化
  watch: {},
  // 方法集合
  methods: {
    // handler() {
    //   this.$store.commit("moduleA/changeName");
    // },
    ...mapMutations(["changeName"]),
    // handler2() {
    //   this.$store.dispatch("moduleA/actChangeName");
    // },
    ...mapActions(["actChangeName"]),
  },
  beforeCreate() {}, // 生命周期 - 创建之前
  // 生命周期 - 创建完成(可以访问当前this实例)
  created() {
    console.log(this.$store);
  },
};
</script>

<style>
</style>

Logo

前往低代码交流专区

更多推荐