Vuex 教程 从入门到实践

​一 核心概念与适用场景​

  • ​Vuex​​Vue.js​​集中式状态管理​ 库,采用​单一状态树​ ,以可预测的方式管理应用中多个组件共享的数据。其核心包含五部分:​State​ (状态)、​Getters​ (派生状态)、​Mutations​ (同步修改)、​Actions​ (异步调度)、​Modules​ (模块化)。适用于​跨多组件共享数据​​复杂表单​​购物车/登录状态​​路由守卫依赖的全局状态​ 等场景。数据流遵循:组件触发 ​Action​​Action​ 执行异步并提交 ​Mutation​​Mutation​ 同步修改 ​State​ → 视图响应更新。

​二 环境搭建与项目结构​

  • 安装(Vue 2 项目):执行命令:npm install vuex@3 --save(Vuex 3 适配 Vue 2)。

  • 目录结构建议:

    javascript 复制代码
    src/
    ├── store/
    │   ├── index.js          # 创建 store 实例
    │   ├── state.js          # 全局状态
    │   ├── mutations.js      # 同步修改
    │   ├── actions.js        # 异步操作
    │   ├── getters.js        # 派生数据
    │   └── modules/          # 模块化(可选)
    │       ├── cart.js
    │       └── user.js
    └── main.js               # 引入并注入 store
  • ​main.js​ 中注册:

    javascript 复制代码
    import Vue from 'vue';
    import App from './App.vue';
    import store from './store'; // 路径按项目实际调整
    
    new Vue({ store, render: h => h(App) }).$mount('#app');
  • 说明:在 ​Vue 3​ 项目中应使用 ​Pinia​ (官方推荐),如需使用 Vuex 则选择 ​Vuex 4​

​三 核心 API 与使用示例​

  • State

    • 定义(store/state.js):

      javascript 复制代码
      export default {
        count: 0,
        user: { name: 'Guest' }
      };
    • 读取(组件内):this.$store.state.count

  • Getters

    • 定义(store/getters.js):

      javascript 复制代码
      export default {
        doubleCount: state => state.count * 2,
        userName: state => state.user.name
      };
    • 读取:this.$store.getters.doubleCount

  • Mutations(同步修改,唯一途径)

    • 定义(store/mutations.js):

      javascript 复制代码
      export default {
        INCREMENT(state, payload) {
          state.count += (payload?.step || 1);
        },
        SET_USER(state, user) {
          state.user = { ...state.user, ...user };
        }
      };
    • 提交:this.$store.commit('INCREMENT', { step: 5 })

  • Actions(异步调度,提交 Mutation)

    • 定义(store/actions.js):

      javascript 复制代码
      export default {
        incrementAsync({ commit }, payload) {
          return new Promise(resolve => {
            setTimeout(() => {
              commit('INCREMENT', payload);
              resolve();
            }, 1000);
          });
        },
        async login({ commit }, { username }) {
          // 模拟 API
          const user = await fakeApiLogin(username);
          commit('SET_USER', user);
        }
      };
    • 派发:this.$store.dispatch('incrementAsync', { step: 2 })

  • 辅助函数(简化模板与代码)

    javascript 复制代码
    import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
    
    export default {
      computed: {
        // 数组写法
        ...mapState(['count', 'user']),
        ...mapGetters(['doubleCount', 'userName']),
        // 对象写法(可重命名)
        ...mapState('cart', ['items']) // 模块化时
      },
      methods: {
        // 数组写法
        ...mapMutations(['INCREMENT']),
        ...mapActions(['incrementAsync']),
        // 对象写法(可重命名)
        ...mapActions('cart', { addToCart: 'ADD_ITEM' })
      }
    };
  • 要点:​Mutation 必须是同步函数​​Action 可包含异步​ ,并通过 commit 改变状态;在组件中优先使用​辅助函数​​Composition API​ 风格的 useStore()(Vuex 3/4 提供)。

​四 模块化与命名空间​

  • 当项目变大,建议按功能拆分模块,避免单一文件臃肿,并开启​命名空间​以隔离命名冲突与提升可维护性。

  • 示例:创建 store/modules/counter.js

    javascript 复制代码
    const counter = {
      namespaced: true, // 开启命名空间
      state: () => ({ value: 0 }),
      mutations: {
        UP(state, n = 1) { state.value += n; }
      },
      actions: {
        upAsync({ commit }, n) {
          return new Promise(r => setTimeout(() => commit('UP', n), 300));
        }
      },
      getters: {
        doubled: state => state.value * 2
      }
    };
    export default counter;
  • 在 store/index.js 中注册:

    javascript 复制代码
    import Vue from 'vue';
    import Vuex from 'vuex';
    import counter from './modules/counter';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      modules: { counter }
    });
  • 组件内使用(命名空间模块):

    javascript 复制代码
    import { mapState, mapMutations, mapActions, mapGetters } from 'vuex';
    
    export default {
      computed: {
        ...mapState('counter', ['value']),
        ...mapGetters('counter', ['doubled'])
      },
      methods: {
        ...mapMutations('counter', ['UP']),
        ...mapActions('counter', ['upAsync'])
      }
    };
  • 说明:开启命名空间后,访问路径变为 store.state.counter.valuestore.getters['counter/doubled']store.commit('counter/UP')store.dispatch('counter/upAsync');辅助函数通过第二个参数指定命名空间,或在模板中使用带前缀的路径。

​五 实战示例 计数器与异步任务​

  • 目标:实现一个计数器,支持​同步增加​​异步增加​ ,并在页面显示​双倍值​
  • 步骤
    1. 定义模块(store/modules/counter.js,见上节)。

    2. 在组件中使用:

      javascript 复制代码
      <template>
        <div>
          <p>Count: {{ value }}</p>
          <p>Double: {{ doubled }}</p>
          <button @click="localIncrement">+1</button>
          <button @click="localIncrementBy(3)">+3</button>
          <button @click="asyncUp">Async +2</button>
        </div>
      </template>
      
      <script>
      import { mapState, mapGetters, mapMutations, mapActions } from 'vuex';
      
      export default {
        computed: {
          ...mapState('counter', ['value']),
          ...mapGetters('counter', ['doubled'])
        },
        methods: {
          ...mapMutations('counter', ['UP']),
          ...mapActions('counter', ['upAsync']),
          localIncrement() { this.UP(); },
          localIncrementBy(n) { this.UP({ step: n }); }
        }
      };
      </script>
    3. 运行与验证:点击按钮观察 countdoubled 的变化;异步操作完成后状态同步更新。

    4. 小贴士:在 ​严格模式​ 下,仅允许通过 ​Mutation​ 修改状态,有助于捕捉非法直接修改;开发阶段可开启以提升可维护性与可调试性。

相关推荐
513495923 分钟前
Vite环境变量配置
vue.js
行走的陀螺仪6 分钟前
.vscode 文件夹配置详解
前端·ide·vscode·编辑器·开发实践
2503_9284115640 分钟前
11.24 Vue-组件2
前端·javascript·vue.js
Bigger1 小时前
🎨 用一次就爱上的图标定制体验:CustomIcons 实战
前端·react.js·icon
谢尔登1 小时前
原来Webpack在大厂中这样进行性能优化!
前端·webpack·性能优化
g***B7381 小时前
JavaScript在Node.js中的模块系统
开发语言·javascript·node.js
Z***25802 小时前
JavaScript在Node.js中的Deno
开发语言·javascript·node.js
weixin79893765432...2 小时前
Vue + Express + DeepSeek 实现一个简单的对话式 AI 应用
vue.js·人工智能·express
高级程序源2 小时前
springboot社区医疗中心预约挂号平台app-计算机毕业设计源码16750
java·vue.js·spring boot·mysql·spring·maven·mybatis
cypking2 小时前
Vue 3 + Vite + Router + Pinia + Element Plus + Monorepo + qiankun 构建企业级中后台前端框架
前端·javascript·vue.js