目录

一、目的

二、模块化应用

2.1 store.js直接应用模块化

2.2 store.js 外部引入

三、开启命名空间后的读取与调用

3.1 state数据

3.2 getters数据

3.3 调用dispatch

3.4 调用commit

四、案例练习

4.1 count.js

4.2 game.js

4.3 index.js - store配置

4.4 Game.vue

4.5 Count.vue


一、目的

让代码更好维护,让多种数据分类更加明确

二、模块化应用

2.1 store.js直接应用模块化

// 引入Vue核心库
import Vue from "vue";
// 引入Vuex
import Vuex from "vuex";
// 应用Vuex插件
Vue.use(Vuex);

// 模块1相关的配置
const 模块名1 = {
    namespace:true, // 开启命名空间
    state:{...},
    actions:{...},
    mutations:{...},
    getters:{...}
}

// 模块2相关的配置
const 模块名2 = {
    namespace:true, // 开启命名空间
    state:{...},
    actions:{...},
    mutations:{...},
    getters:{...}
}

export default new Vuex.Store({
    modules:{
        自定义模块命名1:模块名1,
        自定义模块命名2:模块名2,
    }
})

2.2 store.js 外部引入

让 store.js 更加精简,维护只需要去对应的外部文件

例如:

store外部文件:模块1.js

// 模块1相关配置
export default {
    namespace:true, // 开启命名空间
    state:{...},
    actions:{...},
    mutations:{...},
    getters:{...}
}

store外部文件:模块2.js

// 模块2相关配置
export default {
    namespace:true, // 开启命名空间
    state:{...},
    actions:{...},
    mutations:{...},
    getters:{...}
}

store.js 引入 模块1.js 和 模块2.js

// 引入Vue核心库
import Vue from "vue";
// 引入Vuex
import Vuex from "vuex";

// 引入模块1.js
import 模块名1 from "./模块1.js";

// 引入模块2.js
import 模块名2 from "./模块2.js";

// 应用Vuex插件
Vue.use(Vuex);


export default new Vuex.Store({
    modules:{
        自定义模块命名1:模块名1,
        自定义模块命名2:模块名2,
    }
})

三、开启命名空间后的读取与调用

3.1 state数据

开启命名空间后,组件读取state数据:

// 方式一:自己直接读取, dataName代指state内自己命名的数据
this.$store.state.自定义模块命名.dataName
.....

// 方式二:借助mapState读取
...mapState('自定义模块命名',['dataName','...','...'])

3.2 getters数据

开启命名空间后,组件读取getters数据:

// 方式一:自己直接读取, dataName代指getters内自己命名的数据
this.$store.getters['自定义模块命名/dataName']
.....

// 方式二:借助mapGetters读取
...mapGetters('自定义模块命名',['dataName','...','...'])

3.3 调用dispatch

开启命名空间后,组件中调用dispatch:

// 方式一:自己直接dispatch, data代值传入的数据
this.$store.dispatch('自定义模块命名/actions中方法名', data)
.....

// 方式二:借助mapActions
...mapActions('自定义模块命名',{事件1: "actions中方法名1", 事件2: "actions中方法名2",...})

3.4 调用commit

开启命名空间后,组件中调用commit:

// 方式一:自己直接commit, data代值传入的数据名
this.$store.commit('自定义模块命名/mutations中方法名', data)
.....

// 方式二:借助mapMutations
...mapMutations('自定义模块命名',{事件1: "mutations方法1", 事件2: "mutations方法2",...})

四、案例练习

Vue知识点整理(五)- vuex(2)中 第三节 多组件数据共享 案例 为基础

4.1 count.js

将 求和组件相关 的 store配置项封装到count.js中

// 求和相关的配置
export default {
  namespaced: true,
  actions: {
    add(context, value) {
      context.commit("ADD", value);
    },
    sub(context, value) {
      context.commit("SUB", value);
    },
    addOdd(context, value) {
      if (context.state.sum % 2) {
        context.commit("ADD", value);
      }
    },
    addWait(context, value) {
      setTimeout(() => {
        context.commit("ADD", value);
      }, 1000);
    },
  },
  mutations: {
    ADD(state, value) {
      state.sum += value;
    },
    SUB(state, value) {
      state.sum -= value;
    },
  },
  state: {
    sum: 0,
  },
  getters: {
    bigSum(state) {
      return state.sum * 10;
    },
  },
};

4.2 game.js

将 游戏列表组件相关 的 store配置项封装到game.js中,其中actions中添加了"addE"事件相关内容以及addNameServer事件联系后端API发送请求(异步事件),访问免费小语录API;getters中存放了 firstGameName数据 - 用于显示当前列表第一个的数据名

import axios from "axios";
import { nanoid } from "nanoid";
// 游戏列表相关的配置
export default {
  namespaced: true,
  actions: {
    addE(context, value) {
      if (value.name.indexOf("E") === 0) {
        context.commit("ADD_GAME", value);
      } else {
        alert("添加的游戏必须带有大写字母E");
      }
    },
    addNameServer(context) {
      axios.get("https://api.uixsj.cn/hitokoto/get?type=social").then(
        (response) => {
          context.commit("ADD_GAME", { id: nanoid(), name: response.data });
          console.log(response);
        },
        (error) => {
          alert(error.message);
        }
      );
    },
  },
  mutations: {
    ADD_GAME(state, value) {
      state.gameList.unshift(value);
    },
  },
  state: {
    gameList: [{ id: "001", name: "Splatoon3" }],
  },
  getters: {
    firstGameName(state) {
      return state.gameList[0].name;
    },
  },
};

4.3 index.js - store配置

引入了 count.js模块 和 game.js模块 并命名

// 引入Vue核心库
import Vue from "vue";
// 引入Vuex
import Vuex from "vuex";
// 应用Vuex插件
Vue.use(Vuex);

import countOption from "./count";
import gameOption from "./game";

// 创建并暴露store
export default new Vuex.Store({
  modules: {
    countAbout: countOption,
    gameAbout: gameOption,
  },
});

4.4 Game.vue

添加了 addE事件 和 addNameServer事件相关按钮,并修改了开启命名空间后的state、getters的读取与actions、mutations的调用

<template>
  <div style="padding: 20px">
    <h1>游戏列表</h1>
    <input type="text" placeholder="请输入游戏名" v-model="name" />
    <button @click="add">添加</button>
    <button @click="addE">添加含大写字母E的游戏</button>
    <button @click="addNameServer">添加Server生成语录</button>
    <h3>上方Count组件求和为:{{ sum }}</h3>
    <h3>列表中第一个数据是:{{ firstGameName }}</h3>
    <ul>
      <li v-for="g in gameList" :key="g.id">{{ g.name }}</li>
    </ul>
  </div>
</template>

<script>
import { mapState } from "vuex";
// 引入nanoid-第三方
import { nanoid } from "nanoid";
export default {
  name: "Game",
  data() {
    return {
      name: "",
    };
  },
  computed: {
    ...mapState("gameAbout", ["gameList"]),
    sum() {
      return this.$store.state.countAbout.sum;
    },
    firstGameName() {
      return this.$store.getters["gameAbout/firstGameName"];
    },
  },
  methods: {
    add() {
      const gameObj = { id: nanoid(), name: this.name };
      this.$store.commit("gameAbout/ADD_GAME", gameObj);
      this.name = "";
    },
    addE() {
      const gameObj = { id: nanoid(), name: this.name };
      this.$store.dispatch("gameAbout/addE", gameObj);
      this.name = "";
    },
    addNameServer() {
      this.$store.dispatch("gameAbout/addNameServer");
    },
  },
};
</script>

<style></style>

4.5 Count.vue

修改了开启命名空间后的state、getters的读取与actions、mutations的调用

<template>
  <div style="padding: 20px">
    <h1>当前求和为:{{ sum }}</h1>
    <!-- 模板中添加一个需要引入加工数据的模块 -->
    <h3>当前求和放大10倍为:{{ bigSum }}</h3>
    <h3>下方组件游戏个数:{{ gameList.length }}</h3>
    <select v-model="n">
      <option :value="1">1</option>
      <option :value="2">2</option>
      <option :value="3">3</option>
    </select>
    <!-- 注意:mapActions 与 mapMutations,若需要传递参数则需要:在模板中绑定事件时传递好参数,否则参数是事件对象 -->
    <button @click="increment(n)">+</button>
    <button @click="decrement(n)">-</button>
    <button @click="incrementOdd(n)">当前求和为奇数再加</button>
    <button @click="incrementWait(n)">等1s后再加</button>
  </div>
</template>

<script>
// 引入mapState, mapGetters, mapActions, mapMutations
import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
export default {
  name: "Count",
  data() {
    return {
      n: 1, // 用户选择的数字
    };
  },

  computed: {
    // 借助mapState生成计算属性 - 数组写法
    ...mapState("countAbout", ["sum"]),
    ...mapState("gameAbout", ["gameList"]),

    // 借助mapGetters生成计算属性 - 对象写法
    ...mapGetters("countAbout", { bigSum: "bigSum" }),
  },
  methods: {
    // 靠mapMutations生成与mutations对话的方法 - 对象形式
    ...mapMutations("countAbout", { increment: "ADD", decrement: "SUB" }),
    // 靠mapActions生成与actions对话的方法 - 对象形式
    ...mapActions("countAbout", {
      incrementOdd: "addOdd",
      incrementWait: "addWait",
    }),
  },
};
</script>

<style></style>

 

Logo

前往低代码交流专区

更多推荐