✨ 写在前面
在移动应用开发中,架构设计决定了项目能否高效演进、团队协作是否顺畅、以及未来是否容易维护。在 Flutter 中,我们可以借助 Bloc 来实现一个专业、清晰、易测试的 MVVM 架构。本篇将从底层设计理念,到模块组织,再到状态管理实现,完整解析一个可开源、可商用的 Flutter 项目结构。
🧱 核心理念
本架构基于以下设计原则:
MVVM 模式解耦 UI 与逻辑
Bloc 做为 ViewModel 的核心实现
模块化 + 路由解耦 支持独立业务开发和动态扩展
支持开源、测试、生产等多种环境切换
📂 项目结构总览
lib/
├── core/ # 基础设施层(技术支撑)
│ ├── exceptions/ # 全局异常定义
│ ├── network/ # 网络请求封装(如 Dio)
│ ├── utils/ # 通用工具类
│ └── router/ # 全局路由解耦与管理
├── common/ # 通用层(跨业务模块可复用)
│ ├── widgets/ # 通用 UI 组件
│ ├── models/ # 通用业务模型
│ └── services/ # 全局服务(如用户登录状态)
└── module/ # 各业务模块(横向拆分,独立开发)
└── profile/ # 示例模块:用户资料
├── model/ # 业务模型,如 UserModel
├── view/ # 页面层(UI 展示)
├── bloc/ # 状态管理(ViewModel 逻辑)
├── repository/ # 数据仓库(含接口调用)
└── router/ # 页面路径定义
🧠 为什么使用 Bloc 实现 ViewModel?
Bloc 是 Google 官方推荐的状态管理工具,具有以下优势:
完美奏合 MVVM 中的 ViewModel 职责
强类型、明确的事件(Event)与状态(State)设计
易于测试和调试
良好的社区生态,文档丰富
💡在本架构中,每个页面的 ViewModel 就是一个 Bloc 实例,通过监听事件更新状态,再由 UI 层消费这些状态。
🗉 路由设计:模块解耦的关键
使用 BaseModuleRoute 协议,统一管理每个模块的路由信息,实现模块注册与导出:
abstract class BaseModuleRoute {
String get moduleName;
String get entryPath;
Map<String, WidgetBuilder> get routes;
List<String> get exportedPages;
}
全局路由集中在 AppRouter,负责聚合、跳转、容错处理:
static final List<BaseModuleRoute> _modules = [
HomeModuleRoute(),
ProfileModuleRoute(),
];
支持路径 + 参数跳转、URI 解析、找不到页面兜底等功能。
🔄 MVVM 数据流:从 Event 到 UI
Bloc (ViewModel) 层
class UserProfileBloc extends Bloc<UserProfileEvent, UserProfileState> {
final UserRepository repository;
UserProfileBloc(this.repository) : super(UserProfileInitial()) {
on<LoadUserProfile>((event, emit) async {
emit(UserProfileLoading());
try {
final user = await repository.fetchUserProfile();
emit(UserProfileLoaded(user));
} catch (e) {
emit(UserProfileError("加载失败"));
}
});
}
}
View 层(Page)
BlocBuilder<UserProfileBloc, UserProfileState>(
builder: (context, state) {
if (state is UserProfileLoading) return CircularProgressIndicator();
if (state is UserProfileLoaded) return Text(state.user.name);
if (state is UserProfileError) return Text("错误:${state.message}");
return SizedBox.shrink();
},
)
用户触发动作 -> add(event) -> Bloc 处理 -> emit(state) -> UI 层响应状态变化。
💪 易测试、易拟合
由于:
Bloc 是纯 Dart 类,可独立测试(无需 Widget 测试)
所有逻辑集中在
ViewModel层(Bloc),职责清晰各模块独立、UI 纯粹,易于重构和复用
使得此架构非常适合团队协作、大型项目、组件化中台建设等复杂场景。
✅ 总结
| 架构点 | 是否具备 | 说明 |
|---|---|---|
| MVVM 模式 | ✅ | ViewModel 即 Bloc,解耦逻辑与 UI |
| Bloc 状态管理 | ✅ | 拆分 Event/State,强类型、易扩展 |
| 模块化开发 | ✅ | 支持独立模块注册路由与入口 |
| 路由解耦与跳转 | ✅ | Uri/路径解析、参数传递、兜底页面 |
| 易于测试与扩展 | ✅ | 纯 Dart Bloc + Repository 架构 |
📚 推荐工具 & 插件
dio 网络请求封装
go_router(可选)更强路由支持
json_serializable 自动生成模型
📌 最后的话
架构并非“一刀切”方案,而是实践总结与演进结果。 适合自己的才是最好的。
github示例:
https://github.com/Greathao/bloc_mvvm_architecture
bloc:
https://bloclibrary.dev/getting-started/