模块化在spa中需围绕“谁用、何时用、是否可复用”切分:业务组件按路由/功能域自治,封装模板、逻辑、状态与样式;工具模块无ui、职责单一、禁止反向依赖;通信通过url驱动、轻量事件总线、状态快照实现;构建时静态导入核心路径,动态加载非关键模块。

模块化在 SPA 中不是简单按文件夹分目录,而是围绕“谁用、何时用、是否可复用”来切分。业务组件聚焦页面逻辑和用户交互,工具模块负责通用能力封装,二者边界清晰、依赖单向(工具 → 业务,而非反过来)。
业务组件:按路由或功能域组织,自治且可挂载
每个业务组件对应一个明确的用户场景,比如“商品列表页”“订单提交弹窗”“用户资料编辑表单”。它应包含模板结构、交互逻辑、局部状态和样式作用域,不直接操作全局 DOM 或发起跨域请求。
- 用独立 JS 模块导出渲染函数,例如 export function renderProductList(container, props),接收挂载节点和参数,内部完成克隆 template、绑定事件、初始化数据
- 模板写在 中,避免内联 HTML 字符串拼接,提升可读与调试性
- 样式通过类名前缀(如 .product-list__title)或 CSS 自定义属性隔离,不依赖 scoped 属性(原生 HTML 不支持)
- 路由切换时,只调用对应组件的 render 函数,不保留旧组件 DOM 节点,防止内存泄漏和事件残留
工具模块:无 UI、可复用、职责单一
工具模块不渲染任何内容,只提供确定性输入输出的能力,比如 URL 解析、本地缓存封装、防抖节流、API 请求适配器、表单校验规则集。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 例如 src/utils/request.js 导出统一 fetch 封装:支持 baseURL、自动 token 注入、错误标准化处理,业务组件只调用 request('/users'),不重复写 headers 或 try/catch
- 再如 src/utils/router.js 封装 pushState、popstate 监听与参数解析,业务组件无需手动处理 location.pathname 或 search 字符串
- 工具模块禁止引用业务组件,也不依赖具体路由结构;若需配置,通过函数参数传入,而非读取全局变量
- 使用动态 import() 按需加载重型工具(如富文本解析器),但基础工具(如 isEmail、debounce)应静态导入,保障首屏稳定性
模块间通信:避免隐式耦合,优先用显式契约
业务组件之间不直接调用对方方法或修改对方状态。跨组件协作通过三种方式实现:
- URL 驱动:把共享状态映射到查询参数(如 ?tab=shipping&step=2),由路由层统一解析并分发给相关组件,天然支持分享与刷新恢复
- 事件总线(轻量版):用自定义事件 + dispatchEvent / addEventListener,限定在父子或同级组件间,事件名带命名空间(如 'cart:updated'),不滥用全局广播
- 状态快照管理:对需持久化的临时状态(如搜索关键词、筛选条件),统一存入 sessionStorage,并在组件初始化时读取,避免组件销毁后丢失上下文
构建与加载:让模块划分真正落地
模块划分最终要反映在资源加载行为上。静态导入用于核心路径,动态导入用于非关键分支。
- 首页主流程(如登录态检查、导航栏渲染、默认视图)全部静态导入,打包进 main.js,确保首次加载即可用
- 次要功能(如“导出 PDF”按钮点击后才需要的 html2canvas)、长尾页面(如“404 页面”“隐私政策”)用 import() 动态加载,生成独立 chunk
- 所有模块路径使用相对 URL(如 ./components/profile.js),避免 ./profile.js 这类无效路径导致 CORS 或 MIME 错误
- 服务端必须配置 history fallback(如 Nginx 返回 index.html),否则 /user/123 这类真实路径刷新会 404,破坏模块按路由加载的前提
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










