🚀 多端前端架构怎么设计?我总结了这 3 层模型
一、问题的本质:多端为什么会变复杂?
在上一篇中,我提到一个核心问题:
❗多端统一,究竟该怎么做?
很多人的第一反应是:
用一个框架统一所有端(Taro / uni-app)
但在实际项目中,很快就会遇到问题:
- UI 表现不一致
- 性能不可控
- 调试成本极高
- 框架限制严重
🔥 本质原因只有一个:
不同端,本来就不一样
包括:
- 渲染机制(DOM / 原生)
- 交互模型
- 性能瓶颈
👉 所以结论是:
多端统一,不能从 UI 入手
二、核心思路:分层,而不是强行统一
如果 UI 不能统一,那应该统一什么?
答案是:
统一“逻辑”,而不是“界面”
于是我最终采用了一套分层模型:
UI层(各端独立实现)
↓
业务层(modules,共享)
↓
服务层(services,共享)
👉 这套结构,本质上就是:
前端版的 Clean Architecture
三、三层模型详解
接下来逐层拆解这套架构。
1️⃣ UI层:只负责“展示”
✅ 职责:
- 页面结构
- 组件渲染
- 用户交互
❌ 不应该做的事:
❌ 直接调用 API
❌ 写复杂业务逻辑
❌ 管理核心状态
🔥 正确方式:
UI 层只做一件事:
调用业务层(modules)
示例(React):
function UserPage() {
const { user, fetchUser } = useUser()
useEffect(() => {
fetchUser()
}, [])
return <div>{user?.name}</div>
}
👉 UI 变得非常“薄”,只负责展示
2️⃣ 业务层(modules):架构的核心
这是整个系统最重要的一层。
📦 推荐结构:
modules/
├── user/
│ ├── model.ts
│ ├── service.ts
│ ├── hooks.ts
│ ├── store.ts
🔥 核心定义:
modules = 前端领域层(Domain Layer)
✅ 职责:
- 业务逻辑
- 状态管理
- 数据转换
- 组合 API
❌ 严格禁止:
❌ 依赖 UI(React / 小程序组件)
❌ 依赖平台 API(window / wx)
示例:
export function useUser() {
const user = ref(null)
async function fetchUser() {
user.value = await getUser()
}
return { user, fetchUser }
}
👉 不同端可以用不同方式消费:
- Web:React hooks / Zustand
- 小程序:自定义 store
⚠️ 常见错误(非常重要)
❌ 把 modules 写成 utils
❌ 在组件里直接写业务逻辑
❌ 到处直接调 API
👉 结果就是:
代码不可维护 + 无法复用
3️⃣ 服务层(services):数据统一入口
这一层主要负责:
与后端交互
推荐方式:
OpenAPI → 自动生成 TS services
示例:
export async function getUser() {
return request('/api/user')
}
✅ 优势:
- 类型安全
- 自动同步接口
- 避免手写错误
❗ 关键点:必须有 request 层
因为不同端请求方式不同:
Web → fetch / axios
小程序 → wx.request
👉 如果不做抽象:
services 无法跨端复用
四、三层之间的“边界规则”(核心中的核心)
这部分,是整套架构最关键的地方。
🔥 三条铁律:
1. UI 只能调用 modules
2. modules 只能调用 services
3. services 不能包含业务逻辑
🔁 调用关系:
UI → modules → services → 后端
❌ 错误示例:
UI → services(跳过 modules)
modules → UI(反向依赖)
services → modules(污染)
👉 一旦破坏边界:
整个架构会迅速崩塌
五、为什么这套模型适合“多端”?
因为它天然解决了一个关键问题:
🔥 “什么可以复用?”
| 类型 | 是否复用 |
|---|---|
| UI | ❌ |
| 业务逻辑 | ✅ |
| API | ✅ |
| 设计规范 | ✅ |
👉 换句话说:
跨端复用的核心,是“逻辑”,不是“组件”
六、一句话总结这套架构
用 UI 层适配平台
用 modules 层统一业务
用 services 层统一数据
七、结语:架构的本质是“控制复杂度”
很多人觉得前端复杂,是因为页面多、需求多。
但真正的复杂度来自:
代码没有边界
👉 分层的意义就是:
把复杂度“隔离”在不同层中
🔥 最后一条结论:
好的架构,不是让代码更少
而是让复杂度更可控
下一篇,我会继续讲:
👉 如何用 Monorepo,把这套架构真正落地。