Skip to content

Vue3 之 Vuex

bash

Vue3里面使用Vuex必须用到useStore模块
  • 使用模块版本

  • 不使用模块版本

不使用模块版本

  • Vuex 里面的数据
js
import { createStore } from "vuex";

export default createStore({
  state: {
    message: "初始数据",
  },
  mutations: {
    changemessage(state, value) {
      state.message = value;
    },
  },
  actions: {},
  modules: {},
});
  • 使用 State 里面的数据

  • 改变数据必须用 commit 方法,而不能直接使用

html
<template>
  <div>
    {{ message }}
    <button @click="changevuex">改变数据</button>
  </div>
</template>

<script>
  import { computed, reactive, toRefs } from "vue";
  import { useStore } from "vuex";
  export default {
    setup() {
      const Store = useStore();
      const data = reactive({
        message: computed(() => {
          return Store.state.message;
        }),
        changevuex() {
          Store.commit("changemessage", "改变数据了");
        },
      });
      return {
        ...toRefs(data),
      };
    },
  };
</script>

<style lang="scss" scoped></style>

使用模块版本

新建模块

js
const moduleA = {
  namespaced: true,
  state: {
    message: "ModuleA 里面的信息",
  },
  mutations: {
    changemessage(state, value) {
      state.message = value;
    },
  },
  actions: {},
  getters: {},
};
export default moduleA;

在 Vuex 中使用

js
import { createStore } from "vuex";
import OneContent from "./modules/One";
export default createStore({
  state: {},
  mutations: {},
  actions: {},
  modules: {
    ModuleA: OneContent,
  },
});

在组件里面使用

html
<template>
  <div>
    {{ message }}
    <button @click="changevuex">改变数据</button>
  </div>
</template>

<script>
  import { computed, reactive, toRefs } from "vue";
  import { useStore } from "vuex";
  export default {
    setup() {
      const Store = useStore();
      const data = reactive({
        message: computed(() => {
          return Store.state.ModuleA.message;
        }),
        changevuex() {
          Store.commit("ModuleA/changemessage", "改变数据了");
        },
      });
      return {
        ...toRefs(data),
      };
    },
  };
</script>

<style lang="less" scoped></style>

actions

  • commit 意味着同步。而 actions 意味着异步

  • actions 一般用于获取数据的时候使用

  • 使用 actions 的时候 必须是 dispatch

  • Vuex 里面使用

javascript
/*
 * @Author: Trigger
 * @Date: 2022-01-01 10:32:37
 * @LastEditTime: 2022-01-01 12:53:54
 * @Description: file content
 */
import { login } from "@/api/sys";

import md5 from "md5";

import { setItem, getItem, removeAllItem } from "@/utils/storage";

import { TOKEN } from "@/constant/index.js";

export default {
  namespaced: true,
  state: () => ({
    message: "用户下面的内容",
    token: getItem(TOKEN) || "",
  }),
  mutations: {
    setToken(state, value) {
      state.token = value;
      setItem(TOKEN, value);
    },
    removeToken(state) {
      state.token = "";
      removeAllItem();
    },
  },
  actions: {
    // context 上下文
    /* 登录请求注册 */
    login(context, userInfo) {
      const { username, password } = userInfo;
      return new Promise((resolve, reject) => {
        //异步操作
        login({
          username,
          password: md5(password),
        })
          .then((data) => {
            // 触发mutaions
            this.commit("user/setToken", data.token);
            resolve(data);
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
  },
};
  • 组件里面发射出去(因为我上面返回是一个 promise 对象。所以能用 then)
bash

Store.dispatch("user/login", state.formdata)
  .then((res) => {
    // 登录成功
    console.log(res);
    state.loading = false;
    setItem("username", state.formdata.username);
    // 面包屑
    const breaddata = JSON.stringify([{ name: "首页", path: "/" }]);
    Store.commit("breadurl/changedata", [{ name: "首页", path: "/" }]);
    sessionStorage.setItem("breadurl", breaddata);
    // 导航
    Store.commit("taburl/changetaburl", [{ name: "首页", path: "/" }]);
    sessionStorage.setItem("taburl", breaddata);
    // 导航结束
    Router.push({
      path: "/",
    });
  })
  .catch((error) => {
    console.log(error);
  });
  • 模块之间互相通信

比如 A 模块要使用 B 模块的数据,只有利用 action 里面的 context 这个里面能获取到所有

javascript
/*
 * @Author: Trigger
 * @Date: 2022-01-01 10:32:37
 * @LastEditTime: 2022-01-01 12:53:54
 * @Description: file content
 */
import { login } from "@/api/sys";

import md5 from "md5";

import { setItem, getItem, removeAllItem } from "@/utils/storage";

import { TOKEN } from "@/constant/index.js";

export default {
  namespaced: true,
  state: () => ({
    message: "用户下面的内容",
    token: getItem(TOKEN) || "",
  }),
  mutations: {
    setToken(state, value) {
      state.token = value;
      setItem(TOKEN, value);
    },
    removeToken(state) {
      state.token = "";
      removeAllItem();
    },
  },
  actions: {
    // context 上下文
    /* 登录请求注册 */
    login(context, userInfo) {
      console.log(context); //这样这里面能获取到所有模块的数据
      const { username, password } = userInfo;
      // 跨模块调用 必须后面加入root:true 否则直接报错
      // 本模块调用 则前面不需要加入模块名
      // mutations 方法就是commit
      // actions 方法就是dispatch
      context.commit("loginModules/setToken", "", { root: true });
      context.commit("setUserInfo", {});
      return new Promise((resolve, reject) => {
        //异步操作
        login({
          username,
          password: md5(password),
        })
          .then((data) => {
            // 触发mutaions
            this.commit("user/setToken", data.token);
            resolve(data);
          })
          .catch((error) => {
            reject(error);
          });
      });
    },
  },
};

// 使用的时候仅仅需要在组件里面dispatch一下