MVVM架构在Flutter中的实践:flutter_architecture_samples之MobX篇
在Flutter开发中,状态管理一直是核心挑战之一。本文将以flutter_architecture_samples项目中的MobX实现为例,详细介绍MVVM架构在Flutter中的落地实践。通过具体代码和项目结构,展示如何利用MobX库构建响应式、可维护的Todo应用。
MobX架构概述
MobX是一个基于观察者模式的状态管理库,其核心概念包括Observables(可观察对象)、Actions(动作)和Reactions(反应)。在MobX示例中,这三个概念通过清晰的代码结构实现了分离:
- 状态层:由TodoStore管理应用状态,包含可观察的待办事项列表和过滤条件
- 视图层:通过HomeScreen等Widget展示UI并响应用户交互
- 数据层:通过LocalStorageRepository实现本地存储持久化
核心模块划分
MobX示例的代码组织结构如下:
mobx/
├── lib/
│ ├── stores/ # 状态管理 (ViewModel)
│ │ └── todo_store.dart
│ ├── models/ # 数据模型 (Model)
│ │ └── todo.dart
│ ├── home/ # 视图组件 (View)
│ │ └── home_screen.dart
│ ├── app.dart # 应用入口
│ └── main.dart # 主函数
└── README.md # 模块说明
状态管理实现
可观察状态设计
在TodoStore中,使用@observable注解标记需要被观察的状态变量:
@observable
VisibilityFilter filter;
@observable
ObservableFuture<void> loader;
final ObservableList<Todo> todos;
通过@computed注解实现派生状态,如过滤后的待办事项列表:
@computed
List<Todo> get visibleTodos {
switch (filter) {
case VisibilityFilter.pending:
return pendingTodos;
case VisibilityFilter.completed:
return completedTodos;
case VisibilityFilter.all:
default:
return todos;
}
}
响应式动作实现
用户交互通过@action注解的方法处理,确保状态变更可追踪:
@action
void toggleAll() {
final allComplete = todos.every((todo) => todo.complete);
for (final todo in todos) {
todo.complete = !allComplete;
}
}
@action
void clearCompleted() => todos.removeWhere((todo) => todo.complete);
视图与状态绑定
Observer组件应用
视图层通过Observer组件监听状态变化,实现UI自动更新。在TodoListView中:
@override
Widget build(BuildContext context) {
return Observer(
builder: (context) {
final todos = Provider.of<TodoStore>(context).visibleTodos;
return ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
final todo = todos[index];
return ListTile(
leading: Observer(
builder: (_) => Checkbox(
value: todo.complete,
onChanged: (done) => todo.complete = done,
),
),
title: Text(todo.task),
);
},
);
},
);
}
页面导航与状态共享
通过MobxApp中的Provider实现状态全局共享:
class MobxApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider<TodoStore>(
create: (_) => TodoStore(repository)..init(),
dispose: (_, store) => store.dispose(),
child: MaterialApp(
routes: {
ArchSampleRoutes.home: (context) => const HomeScreen(),
ArchSampleRoutes.addTodo: (context) => AddTodoScreen(
onAdd: (Todo todo) {
Provider.of<TodoStore>(context, listen: false).todos.add(todo);
},
)
},
),
);
}
}
数据持久化处理
本地存储集成
在main.dart中,初始化本地存储仓库并注入到TodoStore:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(
MobxApp(
repository: LocalStorageRepository(
localStorage: KeyValueStorage(
'mobx_todos',
FlutterKeyValueStore(await SharedPreferences.getInstance()),
),
),
),
);
}
自动保存机制
通过MobX的reaction实现状态变更时自动持久化:
_disposeSaveReaction = reaction<List<TodoEntity>>(
(_) => todos.map(todosCodec.encode).toList(),
(todos) => repository.saveTodos(todos),
delay: saveDelay, // 防抖处理
);
实际应用场景展示
添加待办事项
用户通过AddTodoScreen添加新任务,表单验证确保输入有效:
TextFormField(
validator: (val) {
return val.trim().isEmpty
? localizations.emptyTodoError
: null;
},
)
待办事项列表
HomeScreen展示任务列表和统计信息,底部导航切换不同视图:
bottomNavigationBar: Observer(
builder: (context) {
return BottomNavigationBar(
currentIndex: _HomeScreenTab.values.indexOf(_tab.value),
onTap: (int index) {
runInAction(() => _tab.value = _HomeScreenTab.values[index]);
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.list),
title: Text('Todos'),
),
BottomNavigationBarItem(
icon: Icon(Icons.show_chart),
title: Text('Stats'),
)
],
);
},
),
任务详情与编辑
点击任务项打开DetailsScreen,支持查看详情和删除操作:
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => DetailsScreen(
todo: todo,
onRemove: () {
Navigator.pop(context);
onRemove(context, todo);
},
),
),
);
},
项目优势与最佳实践
代码简洁性
相比其他状态管理方案,MobX通过注解和代码生成减少模板代码。以Todo模型为例:
class Todo = _Todo with _$Todo;
abstract class _Todo with Store {
@observable
String task;
@observable
String note;
@observable
bool complete;
}
性能优化
通过细粒度的Observer组件和自动防抖的持久化机制,确保应用性能:
- 只重建变化的Widget子树
- 状态变更合并减少存储操作
可测试性
清晰的分层设计使单元测试更容易实现,如TodoStore测试:
test('toggleAll should check all todos when none are checked', () {
final store = TodoStore(repository);
store.todos.addAll([
Todo(task: 'Task 1'),
Todo(task: 'Task 2'),
]);
store.toggleAll();
expect(store.todos.every((t) => t.complete), isTrue);
});
总结与扩展
MobX为Flutter应用提供了简洁高效的状态管理方案,通过响应式编程模型降低了状态同步的复杂度。本示例展示的架构可扩展到更复杂的应用场景:
- 多Store组合管理复杂状态
- 结合Firebase实现云端同步(firebase_flutter_repository)
- 集成路由管理和依赖注入
更多实现细节可参考:
- 官方文档:mobx/README.md
- 状态管理核心:stores/
- 视图组件:home/
通过MobX的响应式状态管理,开发者可以更专注于业务逻辑实现,构建高性能、易维护的Flutter应用。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考







