Vue 进阶,Vuex 核心概念 + 项目打包发布配置全解析

Vue 开发中,Vuex是状态管理的核心工具(统一管理全局数据),而打包发布是项目上线的关键步骤。

一、Vuex:Vue 的全局状态管理工具

当多个组件需要共享数据(如用户信息、购物车)时,Vuex 可以统一管理这些 "全局状态",避免组件间频繁通信。

1. Vuex 核心概念(5 大模块)

Vuex 的核心由State、Getter、Mutation、Action、Module组成(本文先讲前 4 个基础模块):

(1)State:存储全局状态

State是 Vuex 的 "数据仓库",用于存储全局共享的数据。

示例:

javascript 复制代码
// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

export default new Vuex.Store({
  // 全局状态
  state: {
    userInfo: null, // 用户信息
    cartCount: 0 // 购物车数量
  }
});

组件中使用 State:

vue 复制代码
<!-- 方式1:直接通过$store访问 -->
<div>{{ $store.state.cartCount }}</div>

<!-- 方式2:通过mapState辅助函数(更简洁) -->
<div> {{ cartCount }} </div>
<div> {{ userInfo }} </div>

<script>
import { mapState } from 'vuex';
export default {
  computed: {
    ...mapState(['cartCount', 'userInfo'])
  }
};
</script>

(2)Getter:对 State 的计算属性

Getter类似 Vue 的computed,用于对State进行计算、过滤(结果会缓存)。

示例:

javascript 复制代码
// src/store/index.js
export default new Vuex.Store({
  state: {
    cartList: [
      { id: 1, name: '苹果', count: 2 },
      { id: 2, name: '香蕉', count: 3 }
    ]
  },
  // Getter:计算购物车总数量
  getters: {
    totalCartCount(state) {
      return state.cartList.reduce((sum, item) => sum + item.count, 0);
    }
  }
});

组件中使用 Getter:

vue 复制代码
<!-- 方式1:直接通过$store访问 -->
<template>
  <div>购物车总数:{{ $store.getters.totalCartCount }}</div>
</template>
----------------------
<!-- 方式2:通过mapGetters辅助函数(更简洁) -->
<script>
import { mapGetters } from 'vuex';
export default {
  computed: {
    ...mapGetters(['totalCartCount'])
  }
};
</script>

<template>
  <div>购物车总数:{{ totalCartCount }}</div>
</template>

(3)Mutation:修改 State 的唯一方式

Mutation是同步修改State 的唯一入口(必须是同步函数),用于保证状态变更可追踪。

示例:

javascript 复制代码
// src/store/index.js
export default new Vuex.Store({
  state: { cartCount: 0 },
  // Mutation:定义修改规则
  mutations: {
    // 增加购物车数量
    INCREMENT_CART(state, payload) {
      state.cartCount += payload;
    },
    // 设置用户信息
    SET_USER_INFO(state, userInfo) {
      state.userInfo = userInfo;
    }
  }
});

组件中触发 Mutation:

vue 复制代码
<script>
import { mapMutations } from 'vuex';
export default {
  methods: {
    ...mapMutations(['INCREMENT_CART']),
    addCart() {
      // 方式1:通过mapMutations触发
      this.INCREMENT_CART(1);

      // 方式2:直接通过$store.commit触发
      // this.$store.commit('INCREMENT_CART', 1);
    }
  }
};
</script>

(4)Action:处理异步操作

Action用于处理异步逻辑(如接口请求),最终通过触发Mutation修改 State。

示例:

javascript 复制代码
// src/store/index.js
import { login } from '@/api/user'; // 假设已封装登录接口
export default new Vuex.Store({
  mutations: {
    SET_USER_INFO(state, userInfo) {
      state.userInfo = userInfo;
    }
  },
  // Action:处理异步请求
  actions: {
    async loginAction({ commit }, form) {
      const res = await login(form); // 异步请求
      commit('SET_USER_INFO', res.userInfo); // 触发Mutation修改State
      return res; // 返回结果给组件
    }
  }
});

组件中触发 Action:

vue 复制代码
<script>
import { mapActions } from 'vuex';
export default {
  methods: {
    // 方式1:通过mapActions辅助函数(简化写法)
    ...mapActions(['loginAction']),
    async onLoginByMap() {
      const res = await this.loginAction(this.form);
      console.log('登录成功', res);
    },

    // 方式2:原生$store.dispatch调用(更直观)
    async onLoginByDispatch() {
    // dispatch 和 commit 用法一样, 区别就是 commit 调用的是 mutations 的函数, dispatch 调用的是 actions 的函数
      const res = await this.$store.dispatch('loginAction', this.form);
      console.log('登录成功', res);
    }
  }
};
</script>

二、项目打包发布:核心配置

项目开发完成后,需要打包为静态资源部署到服务器,关键配置包括publicPath和 "路由懒加载"。

1. 配置 publicPath:解决资源路径问题

publicPath用于指定项目部署的基础路径(如部署在子目录/my-app/下),避免打包后资源路径错误。

配置方式:

在vue.config.js中添加:

javascript 复制代码
// vue.config.js
module.exports = {
  // 若部署在根目录,设为'/';若部署在子目录,设为'/子目录名/'
  publicPath: process.env.NODE_ENV === 'production' ? '/my-app/' : '/'
};

2. 路由懒加载:优化打包体积

默认打包会将所有页面代码打包到一个文件中,体积较大。路由懒加载可以将页面拆分为多个小文件,按需加载。

配置方式:

在router/index.js中,将组件导入改为动态导入:

javascript 复制代码
// 原写法:全部打包到一个文件
// import Home from '@/views/Home.vue';

// 懒加载写法:拆分多个文件
const Home = () => import('@/views/Home.vue');
const Login = () => import('@/views/Login.vue');

const routes = [
  { path: '/', component: Home },
  { path: '/login', component: Login }
];

效果:打包后会生成多个chunk文件,访问对应页面时才加载对应的代码,提升首屏加载速度。

相关推荐
程序员大阳7 小时前
副队长JavaScript教程(49)-主动抛出异常与错误类型
javascript·异常处理·error·throw·错误类型
hhhjhl8 小时前
Protobuf.js 跨端三方库仓颉适配全流程
javascript·网络·udp
康小汪8 小时前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
前端·vue.js·人工智能·ai编程·最佳实践
智能运维指南8 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
白山编程大哥10 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Flynt11 小时前
我把热榜那篇"禁用 axios"逐条实测了一遍:结论大体对,坑在它没讲的地方
前端·javascript·axios
Csvn11 小时前
bundle优化
前端
slongzhang_12 小时前
linux 递归删除源码文件|递归删除目录下 *.js,但排除 *.min.js
linux·开发语言·javascript
北冥有鱼12 小时前
发版后动态路由点击报 `Failed to fetch dynamically imported module`」问题上的完整排查与修复过程
前端·vue.js
静默回滚12 小时前
视频压到 25 MB 以内,码率要算、音轨要扣、余量要留
前端