# Nuxt4 + Pinia 前端规范化框架设计规范(终极完整版) # 一、文档概述 ## 1.1 文档基本信息 |项目|说明| |---|---| |文档版本|V1.0| |适用场景|企业级Web应用、IM即时通讯系统、模块化前端项目、需自定义工具库及API服务的项目| |核心技术栈|Nuxt4、Vue3、TypeScript、Pinia| |设计原则|规范化、模块化、高可维护、单向数据流、工具与API统一管控、可扩展| |文档用途|作为项目开发规范基准,统一团队开发标准,指导架构落地、后期迭代与扩展| ## 1.2 设计目标 - 实现前端全局状态中心化、规范化管理,杜绝零散状态污染,确保状态变更可追溯、可管控,对齐后端分层架构思维。 - 自定义工具库统一命名、集中归集,支持全局自动挂载,无需手动导入,提升开发效率,降低代码冗余。 - 工具层支持静态方法调用、new实例化调用两种形态,适配不同业务场景(无状态工具/有状态工具)。 - API服务统一封装、集中管理,支持全局自动导入,可直接实例化调用,简化接口请求流程,统一请求/响应处理逻辑。 - 保障全局长连接(如IM)、登录态稳定,适配后期插件化扩展(多插件商城、用户体系等),确保架构可扩展、不崩解。 - 实现前后端开发规范对齐,降低跨端协作成本,前期立死规矩,后期开发更快、更不乱。 # 二、整体架构设计 ## 2.1 架构核心理念 采用「分层治理 + 模块化拆分」架构,严格遵循单向数据流原则,实现视图、业务逻辑、状态、工具层、API服务层完全解耦;全局状态由Pinia统一管控,自定义工具与API服务统一规约归集,所有公共模块(Stores、Composables、EXTEND工具、API服务)自动注入,简化开发流程,强化团队开发规范一致性,避免代码冗余与混乱,确保项目可维护、可扩展。 ## 2.2 架构分层拓扑 ```plain text 浏览器客户端 ↓ 视图渲染层(Layout布局 + Page页面 + 公共组件) ↓ 业务逻辑层(Composables组合式函数) ↓ 全局工具层(EXTEND结尾自定义工具库) ↓ API服务层(SERVICE结尾接口服务库) ↓ 状态管理层(Pinia模块化仓库) ↓ 数据请求层(API接口、长连接服务) ↓ 后端服务 + 本地持久化缓存(兜底) ``` ## 2.3 工程目录规范(src源码模式) 遵循Nuxt4官方推荐的src目录结构,结合项目需求定制,新增API服务专属目录,确保目录清晰、职责明确,所有核心模块集中归集,便于维护与扩展: ```plain text src/ ├── app.vue # 项目根入口文件,全局样式、全局挂载入口 ├── layouts/ # 全局布局模板,路由切换不销毁(核心常驻组件载体) │ ├── default.vue # 默认主布局(承载导航栏、页脚、IM常驻悬浮组件) │ └── empty.vue # 空白布局(登录页、弹窗、独立页面专用) ├── pages/ # 约定式路由页面,按路由路径组织 │ ├── index.vue # 首页 │ ├── login.vue # 登录页 │ └── im/ # IM模块页面 │ ├── chat.vue # 聊天页面 │ └── contact.vue # 联系人页面 ├── components/ # 全局公共组件,自动导入,按功能分类 │ ├── ui/ # 基础UI组件(Button、Card、Input等) │ └── business/ # 业务组件(IM消息气泡、用户卡片等) ├── stores/ # Pinia状态仓库,模块化拆分,自动导入 │ ├── user.ts # 用户登录状态仓库(登录信息、Token等) │ ├── im.ts # IM聊天状态仓库(未读总数、会话列表等) │ └── app.ts # 全局应用状态仓库(主题、加载态等) ├── composables/ # 业务组合式函数,自动导入,封装复用逻辑 │ ├── useAuth.ts # 权限校验逻辑 │ └── useImSocket.ts # IM长连接逻辑(SignalR/WebSocket封装) ├── extends/ # 【核心】自定义工具库专属目录,统一归集 │ ├── dateEXTEND.ts # 日期处理工具(格式化、日期差等) │ ├── cryptoEXTEND.ts # 加密解密工具(对称加密、Base64等) │ ├── requestEXTEND.ts # 网络请求工具(Axios/ofetch封装、拦截器等) │ └── imHelperEXTEND.ts # IM业务辅助工具(消息格式化、会话处理等) ├── services/ # 【新增核心】API服务专属目录,统一归集,自动导入 │ ├── userSERVICE.ts # 用户相关API服务(登录、获取用户信息等) │ ├── imSERVICE.ts # IM相关API服务(获取会话、发送消息等) │ └── commonSERVICE.ts # 通用API服务(字典查询、文件上传等) ├── types/ # 全局TypeScript类型定义,统一收口 │ ├── user.ts # 用户相关类型(IUserInfo等) │ ├── im.ts # IM相关类型(IMessage、ISession等) │ ├── api.ts # API服务相关类型(请求参数、响应体等) │ └── common.ts # 通用类型(分页、响应体等) ├── utils/ # 底层基础工具函数(无业务逻辑,纯原子方法) │ ├── base64.ts # 基础Base64工具(备用,优先用EXTEND工具) │ └── regex.ts # 正则校验工具(备用,优先用EXTEND工具) └── server/ # Nuxt服务端逻辑(SSR接口、中间件等) ├── api/ # 服务端接口 └── middleware/ # 服务端中间件(权限校验等) ``` # 三、命名规范(强制遵守) ## 3.1 文件命名规范 - 页面/组件文件:采用大驼峰(PascalCase),语义化清晰,如`UserLogin.vue`、`ImChat.vue`;组件按功能分类存放(ui/业务),避免杂乱。 - Pinia状态仓库文件:采用小驼峰(camelCase),以业务域命名,如`user.ts`、`im.ts`,禁止以业务无关名称命名。 - 自定义工具库文件:**固定格式「功能名+EXTEND.ts」,必须以EXTEND结尾,无多余符号**,如`dateEXTEND.ts`、`validateEXTEND.ts`、`imHelperEXTEND.ts`,统一放在`src/extends/`目录下。 - API服务文件:**固定格式「功能名+SERVICE.ts」,必须以SERVICE结尾,无多余符号**,如`userSERVICE.ts`、`imSERVICE.ts`,统一放在`src/services/`目录下。 - 类型文件:采用小驼峰(camelCase),按业务分类,如`user.ts`、`common.ts`、`api.ts`,类型定义统一收口,避免重复定义。 - Composables函数文件:采用小驼峰(camelCase),前缀统一加`use`,如`useAuth.ts`、`useImSocket.ts`,符合Nuxt自动导入约定。 ## 3.2 变量/函数/类命名规范 - 变量/函数:采用小驼峰(camelCase),语义化清晰,禁止使用拼音、简写(通用简写除外,如`uid`),如`loginUser`、`formatTime`。 - 类/接口:采用大驼峰(PascalCase),接口前缀加`I`,如`IUserInfo`、`IMessage`;工具类名称与文件名一致,以EXTEND结尾,如`DateEXTEND`、`CryptoEXTEND`;API服务类名称与文件名一致,以SERVICE结尾,如`UserSERVICE`、`ImSERVICE`。 - 常量:采用全大写(UPPER_CASE),下划线分隔,如`MAX_PAGE_SIZE`、`TOKEN_KEY`,统一放在对应工具、API服务或类型文件中。 # 四、Pinia状态管理规范(核心规范) ## 4.1 核心设计原则 - 单一职责原则:一个仓库只管理一个业务域的状态,禁止跨业务域冗余数据(如用户状态与IM状态分开管理),确保模块解耦。 - 禁止直接修改原则:state为私有状态,**严禁外部直接修改state值**,所有状态变更必须通过actions方法,确保状态变更可追溯、可管控,避免脏数据。 - 计算派生原则:getters作为只读计算属性,封装状态判断、数据格式化、派生逻辑,禁止在组件中重复编写计算逻辑,提升代码复用性。 - 持久化管控原则:仅核心状态(登录Token、用户基础信息)开启持久化,禁止大量数据(如会话列表、消息记录)存入本地,避免占用本地存储、影响性能。 - 自动导入原则:stores目录下所有仓库自动全局导入,无需手动编写import语句,直接调用即可,简化开发流程。 - 类型安全原则:所有状态、方法均需指定TypeScript类型,避免any类型,确保代码健壮性,降低后期维护成本。 ## 4.2 依赖安装与配置 安装Pinia及持久化插件,确保状态持久化功能正常,适配Nuxt4自动导入(同步新增services目录自动导入配置): ```bash # 安装Pinia及Nuxt适配模块 npm install pinia @pinia/nuxt # 安装持久化插件(用于登录态等核心状态兜底) npm install @pinia-plugin-persistedstate/nuxt ``` 在`nuxt.config.ts`中配置,启用Pinia、自动导入Stores、Composables、EXTEND工具、API服务: ```typescript export default defineNuxtConfig({ srcDir: 'src/', // 指定源码目录 modules: [ '@pinia/nuxt', // Pinia Nuxt适配模块 '@pinia-plugin-persistedstate/nuxt' // 持久化插件 ], imports: { dirs: [ 'stores', // 自动扫描Pinia仓库,全局自动导入 'composables', // 自动扫描组合式函数 'extends', // 自动扫描EXTEND工具库,全局自动导入 'services' // 【新增】自动扫描SERVICE API服务,全局自动导入 ] } }) ``` ## 4.3 标准仓库编写格式(可直接复制使用) ```typescript // src/stores/user.ts(用户状态仓库示例) import { defineStore } from 'pinia' import type { IUserInfo } from '~/types/user' // 仓库命名规范:use+业务域+Store(小驼峰),与文件名对应 export const useUserStore = defineStore('user', { // 1. 原始状态:仅存基础数据,不做任何计算、判断,类型明确 state: () => ({ userInfo: null as IUserInfo | null, // 用户基础信息 token: '' as string, // 登录Token isLoading: false as boolean // 登录加载态 }), // 2. 只读计算属性:封装派生逻辑,全局只读,自动缓存,避免重复计算 getters: { // 判断是否登录(核心派生逻辑,统一封装) isLogin: (state) => !!state.token, // 获取用户ID(默认值兜底,避免报错) userId: (state) => state.userInfo?.id ?? 0, // 格式化用户昵称(派生逻辑,组件直接使用) userNickname: (state) => state.userInfo?.nickname || '未知用户' }, // 3. 唯一状态修改入口:所有状态变更必须走actions,可添加日志、校验、拦截 actions: { // 登录成功:设置用户信息与Token setUserInfo(data: IUserInfo, token: string) { this.userInfo = data this.token = token this.isLoading = false }, // 退出登录:清空用户状态 clearUserInfo() { this.userInfo = null this.token = '' this.isLoading = false }, // 设置登录加载态 setLoginLoading(loading: boolean) { this.isLoading = loading } }, // 4. 本地持久化配置:仅缓存核心状态,刷新页面不丢失,避免大量数据存储 persist: { enabled: true, // 开启持久化 strategies: [ { key: 'user-auth-store', // 本地存储key,避免与其他存储冲突 storage: localStorage, // 存储介质(localStorage,前端本地持久化) paths: ['token', 'userInfo'] // 仅持久化指定字段,减少存储开销 } ] } }) ``` ## 4.4 状态使用规范 - 获取状态:优先使用getters获取派生数据,禁止直接读取state(如优先用`userStore.isLogin`,而非`userStore.state.token`),确保逻辑统一。 - 修改状态:必须调用actions方法,禁止直接赋值修改(如`userStore.setUserInfo(data, token)`,禁止`userStore.userInfo = data`),确保状态变更可追溯。 - 跨模块通信:不同仓库之间通过引入对应仓库、调用其actions方法实现通信,禁止直接操作其他仓库的state,避免模块耦合。 - 生命周期:Pinia状态常驻浏览器内存,路由切换、组件销毁时不丢失;刷新页面时,通过persist配置恢复核心状态(如登录态),非核心状态重新初始化。 - 性能优化:Pinia的getters自带缓存特性,重复调用不重复计算;对于复杂状态,可使用shallowRef处理,降低响应式开销。 # 五、EXTEND自定义工具库规范(核心定制规范) ## 5.1 核心规约(强制遵守) - 目录归集:所有自定义工具库必须放在`src/extends/`目录下,禁止散落至其他目录(如utils、composables),确保工具层统一管控,便于查找与维护。 - 命名规范:工具文件名固定为「功能名+EXTEND.ts」,必须以EXTEND结尾,工具类名称与文件名一致(如文件`dateEXTEND.ts`,类名`DateEXTEND`),禁止随意命名。 - 自动挂载:通过Nuxt配置实现extends目录全局自动扫描、自动导入,页面/组件/仓库/API服务中无需手动import,直接使用,提升开发效率。 - 职责边界:工具层仅封装纯逻辑、通用方法,不涉及业务状态修改,不直接操作Pinia仓库;业务相关逻辑下沉至composables,确保工具层复用性。 - 调用形态:支持两种编写与调用形态,可根据业务场景自由选择(无状态工具用静态类,有状态工具用实例化类),兼顾灵活性与规范性。 - 类型安全:工具方法、参数、返回值均需指定TypeScript类型,禁止any类型,确保代码健壮性,便于团队协作。 ## 5.2 工具编写与调用形态(可直接复制使用) ### 形态一:静态类工具(无需new,直接调用) 适合无实例属性、纯工具方法场景(如日期格式化、加密解密、正则校验),无需创建实例,直接通过类名调用方法,简洁高效,全局统一调用入口。 ```typescript // src/extends/dateEXTEND.ts(日期工具示例,静态类) export class DateEXTEND { /** * 格式化时间戳为本地时间字符串 * @param timestamp 时间戳(毫秒) * @returns 格式化后的时间字符串(如:2026-04-09 23:59:59) */ static format(timestamp: number): string { if (!timestamp) return '' const date = new Date(timestamp) const year = date.getFullYear() const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') const hour = String(date.getHours()).padStart(2, '0') const minute = String(date.getMinutes()).padStart(2, '0') const second = String(date.getSeconds()).padStart(2, '0') return `${year}-${month}-${day} ${hour}:${minute}:${second}` } /** * 计算两个时间戳的天数差 * @param start 开始时间戳 * @param end 结束时间戳 * @returns 天数差(正数:end在start之后;负数:end在start之前) */ static diffDay(start: number, end: number): number { const oneDay = 1000 * 60 * 60 * 24 return Math.floor((end - start) / oneDay) } /** * 判断是否为今天 * @param timestamp 时间戳(毫秒) * @returns boolean 是今天返回true,否则返回false */ static isToday(timestamp: number): boolean { const today = new Date() const target = new Date(timestamp) return ( today.getFullYear() === target.getFullYear() && today.getMonth() === target.getMonth() && today.getDate() === target.getDate() ) } } // 调用方式(无需import,全局直接使用) // const time = DateEXTEND.format(Date.now()) // const dayDiff = DateEXTEND.diffDay(startTime, endTime) // const isToday = DateEXTEND.isToday(timestamp) ``` ### 形态二:实例化类工具(支持new创建实例) 适合需要独立实例、携带私有属性场景(如加密解密、请求拦截、多实例独立上下文),通过new创建实例,每个实例拥有独立的私有属性,避免全局污染。 ```typescript // src/extends/cryptoEXTEND.ts(加密工具示例,可实例化) export class CryptoEXTEND { // 私有属性:加密密钥,每个实例独立拥有 private key: string /** * 构造函数:初始化加密密钥 * @param key 加密密钥(不同实例可传入不同密钥) */ constructor(key: string) { this.key = key } /** * 加密字符串(Base64 + 密钥拼接) * @param data 需要加密的字符串 * @returns 加密后的字符串 */ encrypt(data: string): string { // 加密逻辑:拼接密钥后进行Base64编码 const encryptStr = data + this.key return btoa(encodeURIComponent(encryptStr)) } /** * 解密字符串 * @param data 需要解密的字符串 * @returns 解密后的原始字符串 */ decrypt(data: string): string { // 解密逻辑:Base64解码后移除密钥 const decryptStr = decodeURIComponent(atob(data)) return decryptStr.replace(this.key, '') } /** * 验证加密字符串是否有效(匹配当前密钥) * @param data 加密后的字符串 * @returns boolean 有效返回true,否则返回false */ validate(data: string): boolean { try { const decryptStr = this.decrypt(data) return decryptStr !== data // 解密后与原始加密串不一致,说明有效 } catch (error) { return false } } } // 调用方式(无需import,全局直接new实例使用) // const crypto1 = new CryptoEXTEND('custom-key-1') // const encryptData1 = crypto1.encrypt('test-data-1') // const decryptData1 = crypto1.decrypt(encryptData1) // const crypto2 = new CryptoEXTEND('custom-key-2') // 不同密钥的实例 // const encryptData2 = crypto2.encrypt('test-data-2') ``` ## 5.3 工具库使用注意事项 - 工具方法需保证纯函数特性(无副作用),输入相同参数,输出结果一致,便于复用与测试。 - 避免工具库之间相互依赖,若需依赖,需明确依赖关系,避免循环依赖。 - 工具库中禁止直接操作DOM、Pinia状态,所有业务相关操作需通过composables中转。 - 常用工具(如日期、加密)优先使用EXTEND工具库,禁止在组件中重复编写相同逻辑,提升代码复用性。 - API服务中可直接调用EXTEND工具(如请求拦截中使用加密工具),实现逻辑复用。 # 六、SERVICE API服务规范(新增核心规范) ## 6.1 核心规约(强制遵守) - 目录归集:所有API服务必须放在`src/services/`目录下,禁止散落至其他目录(如pages、composables),确保API服务统一管控,便于维护、调试与迭代。 - 命名规范:API服务文件名固定为「功能名+SERVICE.ts」,必须以SERVICE结尾,服务类名称与文件名一致(如文件`userSERVICE.ts`,类名`UserSERVICE`),禁止随意命名。 - 自动挂载:通过Nuxt配置实现services目录全局自动扫描、自动导入,页面/组件/仓库中无需手动import,直接实例化调用,简化接口请求流程。 - 职责边界:API服务仅封装接口请求逻辑(请求参数处理、接口调用、响应数据格式化),不涉及业务逻辑、状态修改;业务逻辑下沉至composables,状态修改通过Pinia actions实现。 - 调用形态:统一采用「实例化调用」,通过new创建服务实例,每个实例可独立配置请求参数、拦截逻辑,适配多场景接口调用(如不同模块的请求头差异)。 - 类型安全:所有API请求参数、响应数据均需指定TypeScript类型(统一在`types/api.ts`中定义),禁止any类型,确保接口调用的健壮性,减少类型错误。 - 请求统一:所有API请求必须通过`extends/requestEXTEND.ts`封装的请求工具,禁止直接使用ofetch/axios调用接口,确保请求拦截、响应拦截、异常处理统一。 ## 6.2 API服务编写与调用形态(可直接复制使用) 统一采用实例化类编写,支持构造函数传入自定义配置(如请求头、超时时间),适配不同业务场景,调用时直接new实例,无需手动导入,符合你的预期调用方式(`const userSerive = new UserSerivce(); var userInfo = userSerive.getinfo();`)。 ```typescript // 第一步:先在types/api.ts中定义请求/响应类型 // src/types/api.ts import type { IUserInfo } from './user' // 用户登录请求参数 export interface ILoginParams { username: string password: string } // 用户登录响应体 export interface ILoginResponse { code: number message: string data: { token: string userInfo: IUserInfo } } // 获取用户信息响应体 export interface IGetUserInfoResponse { code: number message: string data: IUserInfo } // 第二步:编写API服务(src/services/userSERVICE.ts) import type { ILoginParams, ILoginResponse, IGetUserInfoResponse } from '~/types/api' import { RequestEXTEND } from '~/extends/requestEXTEND' // 引入统一请求工具 export class UserSERVICE { // 私有属性:请求工具实例(可自定义配置) private request: RequestEXTEND /** * 构造函数:初始化请求工具,可传入自定义配置 * @param config 自定义请求配置(可选,如超时时间、请求头) */ constructor(config?: { timeout?: number; headers?: Record }) { // 初始化请求工具,传入自定义配置(默认使用全局配置) this.request = new RequestEXTEND(config) } /** * 用户登录接口 * @param params 登录请求参数 * @returns 登录响应数据(格式化后) */ async login(params: ILoginParams): Promise { try { const response = await this.request.post('/api/user/login', params) // 统一响应处理:判断状态码,抛出异常或返回数据 if (response.code !== 200) { throw new Error(response.message || '登录失败') } return response.data // 直接返回核心数据,简化组件调用 } catch (error) { // 统一异常处理:可结合全局提示工具抛出异常 console.error('登录接口异常:', error) throw error // 抛出异常,由调用方处理业务逻辑 } } /** * 获取用户信息接口(需携带Token) * @param userId 用户ID(可选,默认取当前登录用户ID) * @returns 用户信息 */ async getInfo(userId?: number): Promise { try { const response = await this.request.get('/api/user/info', { params: { userId } // 拼接请求参数 }) if (response.code !== 200) { throw new Error(response.message || '获取用户信息失败') } return response.data } catch (error) { console.error('获取用户信息接口异常:', error) throw error } } /** * 退出登录接口 * @returns 退出结果 */ async logout(): Promise { try { const response = await this.request.post<{ code: number; message: string }>('/api/user/logout') return response.code === 200 } catch (error) { console.error('退出登录接口异常:', error) return false } } } // 调用方式(无需import,全局直接new实例使用,完全匹配你的需求) // 1. 基础调用(使用默认配置) // const userService = new UserSERVICE(); // const userInfo = await userService.getInfo(); // 获取当前用户信息 // const loginData = await userService.login({ username: 'admin', password: '123456' }); // 登录 // 2. 自定义配置调用(如设置超时时间、额外请求头) // const userService = new UserSERVICE({ // timeout: 10000, // headers: { 'X-Custom-Header': 'custom-value' } // }); // const userInfo = await userService.getInfo(1001); // 传入用户ID查询指定用户 ``` ## 6.3 API服务使用注意事项 - API服务方法统一使用async/await语法,返回Promise对象,便于组件中异步调用、处理加载态。 - 所有接口请求必须通过`RequestEXTEND`工具,统一处理请求拦截(如添加Token、请求头)、响应拦截(如统一错误提示、Token过期处理)。 - API服务中禁止直接操作Pinia状态,若需修改状态(如登录后设置Token),需在组件/composables中调用API服务后,通过Pinia actions修改。 - 相同业务域的API接口统一放在一个SERVICE文件中,如用户相关接口都放在`userSERVICE.ts`,避免分散。 - 接口参数、响应体类型必须在`types/api.ts`中统一定义,禁止在服务中重复定义类型,确保类型统一。 - 复杂接口(如分页查询)可封装通用方法,传入分页参数,返回格式化后的分页数据,简化组件调用。 # 七、存储分层与性能规范 ## 7.1 存储层级划分 采用「内存为主、磁盘兜底」的存储分层策略,兼顾性能与稳定性,避免性能瓶颈: - 「内存存储(Pinia State)」:全局状态运行时载体,纳秒级读写,性能最优,业务核心读写优先使用。生命周期为页面运行期间,路由切换、组件销毁不丢失,刷新页面后非持久化状态清空。 - 「本地持久化(LocalStorage)」:仅作为Pinia持久化备份,用于存储核心状态(如登录Token、用户基础信息),刷新/重开页面可恢复核心状态。禁止直接操作LocalStorage,统一由Pinia持久化插件托管。 - 「禁止项」:禁止业务代码直接读写LocalStorage;禁止大量列表、非核心数据(如会话列表、消息记录)持久化,避免占用本地存储、影响首屏加载速度与性能。 ## 7.2 性能管控规范 - Pinia性能:getters具备缓存特性,重复调用不重复计算;避免在state中存储大量数据,拆分模块化仓库,降低单个仓库体积。 - 工具库性能:工具方法纯函数封装,避免冗余逻辑;对于计算密集型任务,可考虑使用Web Worker,避免阻塞主线程。 - API服务性能:统一使用请求拦截、响应拦截,添加防抖节流,避免重复请求、无效请求;大文件上传/下载可封装单独方法,支持断点续传。 - 组件性能:全局常驻组件(如IM悬浮窗)放在Layout布局中,避免路由切换时重复创建/销毁;组件懒加载(Lazy前缀),降低首屏加载压力。 - 请求性能:网络请求统一封装在EXTEND工具中,添加请求拦截、响应拦截、防抖节流,避免重复请求、无效请求。 # 八、全局数据流规范 ## 8.1 单向数据流原则(强制遵守) 严格遵循「View → Action → API Service/EXTEND → State → View」的单向闭环数据流,确保数据流可追溯、可管控,避免数据混乱: 1. View(页面/组件):触发用户交互(如登录、发送消息)。 2. Action(调用Store Actions / Composables函数):处理业务逻辑,调用API服务/EXTEND工具请求数据。 3. API Service/EXTEND:API服务调用后端接口获取数据,EXTEND工具处理数据逻辑,返回处理后的数据。 4. State(Pinia仓库):通过Actions更新内存状态,持久化状态自动同步至LocalStorage。 5. View(页面/组件):通过Getters获取状态,自动响应式更新视图。 ## 8.2 通信规范 - 父子组件通信:使用Props/Emits,禁止使用全局状态传递简单父子组件数据。 - 兄弟/跨级组件通信:统一使用Pinia Store,通过修改/读取状态实现通信,禁止使用EventBus、全局变量。 - 页面与布局通信:页面(Page)与布局(Layout)之间的通信,必须通过Pinia Store,确保通信规范、可追溯。 - 长连接通信:IM长连接(SignalR/WebSocket)统一封装在Composables中,通过Pinia Store管理连接状态、消息数据,避免连接混乱。 - API服务与Pinia通信:API服务仅返回数据,不直接操作Pinia状态,由调用方(组件/composables)通过Pinia actions更新状态。 # 九、开发强制约束(必须遵守) - 全局状态统一使用Pinia,禁止使用useState做全局状态共享,禁止使用全局变量、EventBus,避免状态污染。 - 自定义工具必须放在extends目录,文件名以EXTEND结尾,禁止散落其他目录,禁止重复编写相同工具方法。 - API服务必须放在services目录,文件名以SERVICE结尾,禁止散落其他目录,禁止在组件中直接调用接口,必须通过API服务。 - 严禁直接修改Pinia state,所有状态变更必须通过actions,可添加日志、校验、拦截,确保状态变更可追溯。 - 页面与布局分离,全局常驻组件(IM、导航)必须放在layouts/default.vue中,保证长连接不中断、组件不重复销毁/创建。 - 业务逻辑下沉至composables和EXTEND工具,页面组件只做视图渲染,禁止在页面中编写复杂业务逻辑、工具方法、接口调用。 - 所有接口请求统一封装在API服务中,API服务统一使用RequestEXTEND工具,禁止页面直接请求,便于统一拦截、异常处理、请求优化。 - 严格遵循命名规范、目录规范,禁止随意修改目录结构、文件名,确保团队开发一致性。 - 所有代码必须使用TypeScript,禁止any类型,确保类型安全,降低后期维护成本。 - API服务统一采用实例化调用,禁止静态调用,确保每个服务实例可独立配置,适配多场景需求。 # 十、架构优势总结 - 规范化统一:状态、工具、API服务、目录、命名全流程规范,团队开发无歧义,降低协作成本,前期立死规矩,后期开发更快、更不乱。 - 开发高效:公共模块(Stores、Composables、EXTEND工具、API服务)自动导入,无需重复编写import,降低冗余代码,API服务可直接实例化调用,大幅提升开发效率。 - 可维护性强:分层清晰,模块职责单一,状态变更可追溯,工具与API服务统一管控,后期迭代、修改只需动一处,降低维护成本。 - 稳定性高:状态变更有管控,工具层纯逻辑封装,API服务统一请求/响应处理,长连接常驻布局,登录态持久化兜底,避免全局污染、数据混乱,适配高并发场景。 - 可扩展性强:模块化拆分,插件化扩展友好,IM长连接、多插件商城、用户体系可随意扩展,API服务与工具库可独立新增,架构不崩解,一步到位终身舒服。 - 类型安全:全程TypeScript支持,类型定义统一收口,API请求/响应、工具方法、状态均有类型约束,避免类型错误,提升代码健壮性,降低线上bug率。 # 十一、附录:常用命令与依赖清单 ## 11.1 常用命令 ```bash # 初始化Nuxt4项目(src目录模式) npx nuxi init my-project --src-dir # 进入项目目录 cd my-project # 安装核心依赖 npm install pinia @pinia/nuxt @pinia-plugin-persistedstate/nuxt # 安装其他常用依赖(根据需求) npm install axios ofetch scss # 启动开发服务器 npm run dev # 构建生产包 npm run build # 预览生产包 npm run preview ``` ## 11.2 核心依赖清单 |依赖名称|用途| |---|---| |pinia|全局状态管理核心库| |@pinia/nuxt|Pinia适配Nuxt4的模块,支持自动导入| |@pinia-plugin-persistedstate/nuxt|Pinia持久化插件,实现状态本地备份| |ofetch|网络请求工具,统一封装请求逻辑(RequestEXTEND基础)| |axios|备选网络请求工具,可根据需求替换ofetch| |scss|样式预处理器,支持模块化样式| > (注:文档部分内容可能由 AI 生成)