vuex的使用


vuex 介绍

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

初始化项目

  1. 使用 vue create my-vuex
  2. 安装 vuex:npm i vuex
  3. 安装 vue-router:npm i vue-vue-router

使用 vuex

// ./src/main.js
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";

const app = createApp(App);
app.use(router);
app.use(store);

app.mount("#app");

开始使用

文件目录

|-- ./src
|   |-- ./src/App.vue
|   |-- ./src/main.js
|   |-- ./src/router
|   |   `-- ./src/router/index.js
|   |-- ./src/store
|   |   |-- ./src/store/index.js
|   |   `-- ./src/store/modules
|   |       `-- ./src/store/modules/about.js
|   `-- ./src/views
|       |-- ./src/views/AboutView.vue
|       `-- ./src/views/HomeView.vue
<!-- ./src/App.vue -->
<script setup>
  import { RouterLink, RouterView } from "vue-router";
</script>

<template>
  <header>
    <div class="wrapper">
      <h1>App组件</h1>
      <!-- template 中获取 状态 -->
      <h3>APP 当前计数:{{ $store.state.count }}</h3>
      <hr color="red" />
      <section>
        <nav>
          <RouterLink to="/">Home</RouterLink>
          <RouterLink to="/about">About</RouterLink>
        </nav>
      </section>
    </div>
  </header>
  <RouterView />
</template>

<style scoped>
  nav a.router-link-exact-active {
    color: red;
  }
  a {
    margin-left: 20px;
  }
</style>
// ./src/router/index.js
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue";

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: "/",
      name: "home",
      component: HomeView,
    },
    {
      path: "/about",
      name: "about",
      component: () => import("../views/AboutView.vue"),
    },
  ],
});

export default router;
// ./src/store/index.js
import { createStore } from "vuex";
import aboutModule from "./modules/about";

const store = createStore({
  modules: {
    about: aboutModule,
  },
  state: () => ({
    count: 10,
    name: "hahaha",
    age: 18,
    names: [
      { id: 1, name: "a" },
      { id: 2, name: "b" },
      { id: 3, name: "c" },
    ],
    // 服务器中的数据
    data: [],
  }),
  /**
   * mutation的重要原则:
   * 1.mutation 必须是同步函数
   * 因为 devtool工具会记录 mutation的日志;
   * 每一条 mutation被记录,devtools都需要捕捉到前一个状态和后一个状态的快照;
   * 但是mutation中执行异步操作,就无法追踪到数据的变化
   *
   */
  mutations: {
    increment(state) {
      state.count++;
    },
    changeName(state) {
      state.name = "你好啊";
    },
    changeAge(state, age) {
      state.age += age;
    },
    changeData(state, data) {
      state.data = data;
    },
  },
  // 某些数据经过变化进行使用
  getters: {
    formatName(state) {
      return state.name.toLocaleUpperCase();
    },
    message(state, getters) {
      // 可以获取到 gerters
      return `${getters.formatName}` + state.age;
    },
    getName(state) {
      return function (id) {
        const nameRes = state.names.find((item) => item.id === id);
        return nameRes;
      };
    },
  },
  actions: {
    incrementAction(context) {
      // contetx 中有 commit,dispatch,getters,rootGetters,rootState,state
      context.commit("increment");
    },
    fetchHomeMutidataAction(context) {
      fetch("https://jsonplaceholder.typicode.com/users")
        .then((res) => {
          return res.json();
        })
        .then((data) => {
          console.log(data, "---");
          context.commit("changeData", data);
        });
    },
  },
});

export default store;
// ./src/store/modules/about.js
export default {
  state: () => ({
    about: "about------state",
  }),
};
./src/views/AboutView.vue
<script setup></script>
<template>
  <div class="about">
    <h2>About 页面</h2>
    <h3>{{ $store.state.about.about }}</h3>
  </div>
</template>

<style></style>
<!-- ./src/views/HomeView.vue -->
<script setup>
  import { toRefs } from "vue";
  import { useStore } from "vuex";
  const store = useStore();
  // 发起网络请求
  store.dispatch("fetchHomeMutidataAction");
  const { data } = toRefs(store.state);
</script>

<template>
  <main>
    <h2>Home 页面</h2>
    <ul v-if="data.at(-1)">
      <template
        v-for="item in data"
        :key="item.id"
      >
        <li>{{ item.username }}</li>
      </template>
    </ul>
    <h3 v-else>loading...</h3>
  </main>
</template>

文章作者: PaoMo
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 PaoMo !
  目录