单页面应用中应按业务功能而非文件类型划分模块,每个模块自包含界面、逻辑、数据和路由,通过显式接口解耦、路由作为边界、动态导入实现自治。

在单页面应用(SPA)中按业务功能划分模块,核心是让每个模块自包含、职责单一、边界清晰,而不是按文件类型(比如全把组件放 components/、全把 API 放 services/)粗暴归类。
按功能组织目录结构
每个业务模块应有自己的完整能力栈,包括界面、逻辑、数据层和路由配置。例如用户中心模块不是只放组件,而是:
-
src/features/user/—— 模块根目录 -
src/features/user/components/—— 仅该模块专用的 UI 组件(如UserCard.vue) -
src/features/user/services/—— 封装该模块专属 API(如fetchUserProfile()) -
src/features/user/store/或src/features/user/hooks/—— 状态管理或业务逻辑钩子(如useUserEdit()) -
src/features/user/router.ts—— 定义该模块的路由(如/user/profile),支持懒加载 -
src/features/user/index.ts—— 统一入口,导出模块可被外部调用的能力(如默认导出 setup 函数或路由配置)
模块间解耦靠显式依赖与约定接口
避免模块直接跨目录 import 对方内部文件(比如 features/user/components/UserForm 直接引用 features/order/utils/formatPrice)。正确做法是:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 通用能力下沉到
shared/或common/(如日期格式化、请求拦截器、全局常量) - 模块对外只暴露明确的 API,比如通过
index.ts导出一个 hooks 集合或 service 工厂函数 - 跨模块通信走事件总线、状态共享(Pinia/Vuex store 的 domain slice)或 URL 参数 + 路由守卫,而非直接调用对方私有方法
路由即模块边界
在 SPA 中,路由路径天然对应业务场景,应作为模块划分的主线索:
立即学习“Java免费学习笔记(深入)”;
- 每个功能模块配独立路由文件,支持动态导入:
{ path: '/profile', component: () => import('./features/user/views/ProfileView.vue') } - 模块内路由嵌套(如
/user/settings/security)应在该模块内部定义,不污染根路由表 - 配合路由元信息(
meta: { module: 'user' })便于权限控制、埋点或按模块预加载资源
构建与加载支持模块自治
模块要真正“独立”,需配套工程能力:
- 使用 Vite 或 Webpack 的 dynamic import 实现模块级代码分割,打包后每个模块生成独立 chunk
- 配置路径别名(如
@/features/user),减少相对路径错误 - 模块内可自带单元测试(
__tests__/)和 Storybook 示例,不依赖整个项目启动 - 避免
src/features/user/index.ts中 import 全局 store 或 router 实例——改用参数注入或 composable 封装

















