模块边界隔离业务状态需通过接口契约与状态边界实现,禁止跨模块直接读写;各模块独占状态责任域,初始化自主完成,跨模块访问须经只读selector或服务层中转,通信遵循事件总线、服务层、状态桥接三层规范,并用工具链强制约束。

用模块边界隔离业务状态
不同业务线的状态混在一起,容易互相污染——比如A业务修改了全局用户信息,B业务跟着出错。模块化不是简单拆文件夹,而是通过明确的接口契约和状态边界,让每个业务线只关心自己的数据流。核心是:状态不跨模块直接读写,所有共享数据必须走定义好的通信机制。
定义清晰的模块职责与状态归属
每个模块应有唯一且不可重叠的状态责任域。例如「订单模块」只管理 orderList、currentOrder、paymentStatus 等与订单强相关的状态;「用户模块」负责 profile、authToken、permissions;「营销模块」维护 couponList、activityStatus。禁止在订单页里直接修改 user.permissions 或调用 marketing.setCouponUsed()。
- 状态初始化由所属模块自主完成(如 useOrderStore() 内部调用 api.getOrderList())
- 跨模块读取状态,统一走只读 selector 或 context API,不暴露可变引用
- 状态变更指令(如“申请优惠券”)发事件或调用 service 方法,由目标模块内部消化并更新自身状态
建立跨模块通信的规范路径
避免模块间硬依赖或双向调用。推荐三层通信结构:
- 事件总线(轻量场景):使用发布-订阅模式,如 emit('coupon:applied', { id }),仅传递必要数据,不携带状态实例
- 服务层中转(主干逻辑):将跨域操作封装为 service,如 marketingService.applyCoupon(),内部协调用户权限校验、库存扣减、订单刷新等,调用方只关心结果
- 组合式状态桥接(Vue/Pinia 或 React+Zustand 场景):在页面级 store 中聚合多个模块状态,但保持只读映射,变更仍委托给对应模块的 action
协作落地的关键工程约束
光靠约定不够,需工具链保障:
- 模块目录强制包含 state.ts、service.ts、events.ts,CI 检查缺失项
- ESLint 插件拦截跨模块直接 import 状态 store(如禁止 import { useUserStore } from '@/modules/marketing')
- Storybook 中每个模块提供独立状态快照视图,支持手动触发事件验证响应行为
- 模块间接口变更必须提 MR + 更新 OpenAPI 描述,并通知依赖方










