# vue-app-frame **Repository Path**: ymc-x/vue-app-frame ## Basic Information - **Project Name**: vue-app-frame - **Description**: 创建初衷是为了搭建一套通用且通俗易懂,又符合行业最佳实践的前端架构。之后可以根据业务场景直接使用此架构进对项目快速开发,避免每次重复架构,只需要关注组件的开发。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-09-05 - **Last Updated**: 2025-09-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 通用前端架构核心技术栈 详细说明文档 ## 1. 项目概述 本文档详细解释了搭建的通用前端项目架构的步骤,该项目基于 Vue 3 生态系统构建,采用了现代化的前端开发流程和最佳实践。 ps:创建初衷是为了搭建一套通用且通俗易懂,又符合行业最佳实践的前端架构。之后可以根据业务场景直接使用此架构进对项目快速开发,避免每次重复架构,只需要关注组件的开发。 ## 2. 技术栈选型 ### 2.1 核心技术栈 | 技术/框架 | 版本 | 用途 | 设计优势 | |--------------|----------|------------------------|------------------------------------------| | Vue | ^3.5.18 | 前端框架 | 组合式 API、性能优化、更好的 TypeScript 支持 | | Vite | ^7.1.2 | 构建工具 | 极速开发服务器、按需编译、优化的构建输出 | | TypeScript | ^5.9.2 | 编程语言 | 静态类型检查、代码智能提示、提高代码可维护性 | | Vue Router | ^4.5.1 | 路由管理 | 组件懒加载、动态路由、导航守卫 | | Pinia | ^3.0.3 | 状态管理 | 模块化设计、TypeScript 支持、更简洁的 API | | Axios | ^1.11.0 | HTTP 客户端 | 拦截器机制、请求/响应转换、错误处理 | | Element Plus | ^2.11.1 | UI 组件库 | 丰富的组件、国际化支持、主题定制 | | Mock.js | ^1.1.0 | 模拟数据 | 快速生成模拟数据、独立于后端开发 | | Sass | ^1.92.0 | CSS 预处理器 | 变量、嵌套规则、混入、函数等高级特性 | ### 2.2 开发工具链 | 工具/插件 | 版本 | 用途 | 设计优势 | |---------------------|------------|------------------------|------------------------------------------| | ESLint | ^9.34.0 | 代码质量检查 | 统一代码规范、自动修复常见问题 | | Prettier | ^3.6.2 | 代码格式化 | 保持一致的代码风格、减少代码审查中的格式讨论 | | @vitejs/plugin-vue | ^6.0.1 | Vue 插件 | 支持 Vue 单文件组件、热更新 | | unplugin-auto-import | ^20.1.0 | 自动导入 | 自动导入 Vue、Pinia 等常用 API,减少样板代码 | | unplugin-vue-components | ^29.0.0 | 组件自动注册 | 自动注册组件,无需手动引入 | ## 3. 项目目录结构 ``` vue-app\src\ │ ├── App.vue # 应用根组件 │ ├── api\ # API 相关配置和实现 │ │ ├── index.js # API 实例创建和导出 │ │ ├── interceptors\ # 请求/响应拦截器 │ │ │ ├── index.js # 拦截器配置入口 │ │ │ ├── request\ # 请求拦截器 │ │ │ │ └── auth.js # 认证相关请求拦截 │ │ │ └── response\ # 响应拦截器 │ │ │ ├── data.js # 响应数据处理 │ │ │ └── error.js # 响应错误处理 │ │ ├── mock\ # Mock 数据配置 │ │ │ ├── index.js # Mock 初始化配置 │ │ │ └── modules\ # Mock 数据模块 │ │ │ └── common.js # 通用 Mock 数据 │ │ └── modules\ # API 模块定义 │ │ └── common.js # 通用 API 模块 │ ├── assets\ # 静态资源 │ │ └── vue.svg │ ├── components\ # 公共组件 │ ├── main.js # 应用入口文件 │ ├── router\ # 路由配置 │ │ └── index.js # 路由定义和配置 │ ├── store\ # 状态管理 │ │ ├── index.js # Pinia 初始化 │ │ └── models\ # 数据模型 │ │ └── userStore.js # 用户相关状态 │ └── views\ # 页面视图 │ └── Demo.vue # 示例页面 ├── vite.config.js # Vite 配置文件(用于项目构建) ├── .eslintrc.js # ESLint 配置文件(用于代码质量检查) ├── .prettierrc.js # Prettier 配置文件(用于代码格式化) ├── .gitignore # Git 忽略文件 ├── package.json # 项目依赖配置文件 ├── README.md # 项目说明文档 ### 3.1 目录设计说明 该项目采用了模块化的目录结构设计,遵循职责单一原则,将不同功能的代码分散到不同的目录中,便于维护和扩展: - **src/api/**:集中管理所有与后端 API 交互相关的代码,包括请求封装、拦截器处理和 Mock 数据模拟 - **src/components/**:存放可复用的 UI 组件,提高代码复用率 - **src/router/**:路由配置中心,统一管理页面跳转逻辑 - **src/store/**:状态管理中心,使用 Pinia 实现全局状态共享 - **src/views/**:存放页面级组件,每个文件对应一个完整的页面 ## 4. 核心模块详细分析 ### 4.1 应用入口 (main.js) ```javascript import { createApp } from "vue"; import pinia from "store"; import router from "router"; import App from "./App.vue"; import enableMock from "api/mock"; // 启动mock enableMock(); const app = createApp(App); app.use(pinia); app.use(router); app.mount("#app"); ``` **设计亮点**: - 简洁明了的入口文件,清晰展示了应用的初始化流程 - 模块化导入,提高代码可读性 - 条件性启用 Mock,便于开发和测试环境切换 - 链式调用 app.use() 方法,符合现代 JavaScript 风格 ### 4.2 路由管理 (router/index.js) ```javascript import { createRouter, createWebHistory } from "vue-router"; //动态导入(懒加载 const DemoView = () => import('views/Demo.vue') const routes = [ { path: '/demo', name: 'demo', component: DemoView, meta: { title: 'demo页面', } }, ] const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes, }) export default router; ``` **设计亮点**: - 使用 Vue Router 4 的 `createWebHistory` 模式,支持浏览器历史记录 - 采用路由懒加载方式 (`() => import()`),优化首屏加载速度 - 通过 meta 字段为路由添加额外信息,便于全局处理(如设置页面标题) - 模块化设计,易于扩展更多路由 ### 4.3 状态管理 (store/index.js 和 store/models/userStore.js) #### store/index.js ```javascript import { createPinia } from "pinia"; const pinia = createPinia(); //统一导出所有 Store import { useUserStore } from "./models/userStore"; export default pinia; ``` #### store/models/userStore.js ```javascript import { defineStore } from "pinia"; import { ref, computed } from "vue"; //统一封装属性,避免传值复杂 function initState() { return { user: { name: "张三", age: 18, sex: "男", phone: "13800000000", }, token: '', }; } export const useUserStore = defineStore("userStore", () => { const state = ref(initState()) const increment = () => { } return { state, increment, } }); ``` **设计亮点**: - 使用 Pinia,Vue 3 官方推荐的状态管理解决方案,相比 Vuex 更加简洁 - 采用组合式 API 风格定义 Store,符合 Vue 3 的开发理念 - 状态初始化函数封装,便于管理初始状态 - 模块化设计,每个功能模块对应独立的 Store 文件 - 使用 TypeScript 友好的 API 设计 ### 4.4 API 请求封装 (api/index.js) ```javascript import axios from 'axios' import {setupInterceptors} from './interceptors' //创建实例 const service = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost/api', timeout: 10000, headers: { 'Content-Type': 'application/json' } }) //添加拦截器(社区最佳实践,拆分拦截关注点) setupInterceptors(service) //双重导出(符合社区最佳实践)(原始实例用于特殊情况) export default service export {axios} ``` **设计亮点**: - 使用 Axios 创建自定义实例,便于配置基础 URL、超时时间等 - 利用 Vite 的环境变量 `import.meta.env.VITE_API_BASE_URL` 实现不同环境的配置切换 - 拦截器分离设计,提高代码可维护性 - 双重导出设计,同时导出配置好的实例和原始 axios,满足不同场景需求 ### 4.5 拦截器机制 (api/interceptors/) #### interceptors/index.js ```javascript //请求拦截器 import { requestAuth, requestAuthErrorHandler } from './request/auth' //响应拦截器 import { responseErrorHandler } from './response/error' import { responseDataHandler } from './response/data' export const setupInterceptors = (instance) => { instance.interceptors.request.use( requestAuth(), requestAuthErrorHandler(), ) instance.interceptors.response.use( responseErrorHandler(), responseDataHandler(), ) } ``` #### interceptors/request/auth.js ```javascript import { useUserStore } from 'store/models/userStore' // 请求拦截器 export const requestAuth = (config) => { const token = useUserStore().state.token if (token) { config.headers.Authorization = `Bearer ${token}` } //添加公共参数 if (config.method === 'get') { config.params = { ...config.params, _t: Date.now() //防止缓存 } } return config } // 请求错误处理 export const requestAuthErrorHandler = (error) => { return Promise.reject(error) } ``` #### interceptors/response/data.js ```javascript export const responseDataHandler = (response) => { const { data } = response; //假设后端返回的数据格式为 { code: 200, msg: '成功', data: {...} } if (data && data.code === 200) { return data.data; //返回实际数据 } else { //处理业务错误 const error = new Error(data.msg || '接口返回错误'); error.code = data.code; return Promise.reject(error); } } ``` #### interceptors/response/error.js ```javascript import { message } from 'element-plus' import router from 'router' // 处理响应错误 export const responseErrorHandler = (error) => { const { response } = error if (response) { const { status, msg } = response switch (status) { case 400: message.error(msg || '请求错误'); break; case 401: message.error('未授权,请重新登录'); router.push('/login'); break; case 403: message.error('拒绝访问'); break; case 404: message.error('请求资源未找到'); break; case 500: message.error('服务器内部错误'); break; default: message.error(`连接错误${status}`); } } else { message.error('网络异常,无法连接服务器'); } } ``` **设计亮点**: - **关注点分离**:将请求拦截、响应数据处理、响应错误处理拆分为独立模块 - **统一认证处理**:自动在请求头中添加 Token,实现认证统一管理 - **防缓存策略**:对 GET 请求自动添加时间戳参数,避免浏览器缓存 - **统一错误处理**:对不同 HTTP 状态码进行统一处理,提供友好的错误提示 - **路由重定向**:在未授权情况下自动跳转到登录页面 ### 4.6 Mock 数据模拟 (api/mock/) #### mock/index.js ```javascript /* 模拟数据参数说明: '/xxx/xxx' [为正则地址 默认请求方式为get] '/xxx/xxx@1 | /xxx/xxx @1' [为正则地址 @是否启用(1启用,0不启用,默认跟随整体开关)] '/xxx/xxx get' [为正则地址 请求方式] '/xxx/xxx get@0' [为正则地址 请求方式@是否启用(1启用,0不启用,默认跟随整体开关)] 三层控制说明: 全局开关(VITE_APP_MOCK) 整体开关(VITE_ALL_MOCK) 局部开关@ 最终状态 false 任意 任意 禁用 true true @0 禁用 true true @1 或不设置 启用 true false @0 或不设置 禁用 true false @1 启用 */ import Mock from 'mockjs' import commonMock from './modules/common' // 设置200-900ms随机延时 Mock.setup({ timeout: '200-900' }) // 注册所有模块 const mockModules = [ commonMock, ] //路由健壮性处理 ``` #### mock/modules/common.js ```javascript import Mock from 'mockjs' // 模拟数据 export default { '/common/index get': { code: 200, msg: 'success', data: { appName: '官方客服系统', version: '1.0.0', // 使用 Mock.js 生成随机数据 bannerList: Mock.mock({ 'list|3-5': [{ 'id|+1': 1, title: '@ctitle(5, 10)', image: '@image(300x200, @color, @title)', link: '@url' }] }).list, } }, //登录接口模拟DEMO '/auth/login post@0': (options) => { const { username, password } = JSON.parse(options.body) if (username === 'admin' && password === '123456') { return { code: 200, msg: '登录成功', data: { token: Mock.Random.string(32), userInfo: { id: Mock.Random.id(), username: username, name: '管理员', avatar: Mock.Random.image('100x100', '#ffcc33', 'Avatar'), } } } } else { return { code: 401, msg: '用户名或密码错误', data: {} } } } } ``` **设计亮点**: - **灵活的开关机制**:实现全局、整体、局部三层开关控制,灵活切换 Mock 状态 - **模块化组织**:按业务模块组织 Mock 数据,便于管理和维护 - **智能随机数据**:利用 Mock.js 的模板语法生成丰富的随机数据 - **动态响应**:支持函数式配置,根据请求参数动态返回模拟数据 - **网络延时模拟**:设置随机延时,更真实地模拟网络请求 ### 4.7 根组件 (App.vue) ```vue ``` **设计亮点**: - 简洁的根组件设计,专注于路由视图的渲染 - 使用 Vue 3 的 `