从Typora无缝迁移到Obsidian:我的Markdown工作流升级与避坑全记录(含图片上传、换行设置)
2026/5/31 9:22:18
在 Flutter 开发中,状态管理(State Management)是绕不开的核心话题。随着应用复杂度提升,简单的setState已无法满足需求。目前主流方案包括Provider、Riverpod、Bloc等。本文将通过一个“待办事项(Todo)”应用,对比三种方案的写法、性能与适用场景,并给出选型建议。
图:无状态管理 vs 有状态管理的数据流对比
pubspec.yaml):dependencies: flutter: sdk: flutter provider: ^6.1.0// todo_model.dart class Todo { final String title; bool completed; Todo(this.title, {this.completed = false}); } // todo_provider.dart class TodoProvider with ChangeNotifier { final List<Todo> _todos = []; List<Todo> get todos => _todos; void addTodo(String title) { _todos.add(Todo(title)); notifyListeners(); } void toggle(int index) { _todos[index].completed = !_todos[index].completed; notifyListeners(); } }// main.dart void main() { runApp( ChangeNotifierProvider( create: (_) => TodoProvider(), child: const MyApp(), ), ); } // 在 UI 中使用 Consumer<TodoProvider>( builder: (context, todoProvider, child) { return ListView.builder( itemCount: todoProvider.todos.length, itemBuilder: (context, i) => CheckboxListTile( title: Text(todoProvider.todos[i].title), value: todoProvider.todos[i].completed, onChanged: (_) => todoProvider.toggle(i), ), ); }, )BuildContextdependencies: flutter_riverpod: ^2.5.0final todoProvider = StateNotifierProvider<TodoNotifier, List<Todo>>((ref) { return TodoNotifier(); }); class TodoNotifier extends StateNotifier<List<Todo>> { TodoNotifier() : super([]); void add(String title) { state = [...state, Todo(title)]; } void toggle(int index) { state = [ for (int i = 0; i < state.length; i++) if (i == index) Todo(state[i].title, completed: !state[i].completed) else state[i] ]; } }// UI 中使用(无需 Consumer) @override Widget build(BuildContext context, WidgetRef ref) { final todos = ref.watch(todoProvider); return ListView.builder( itemCount: todos.length, itemBuilder: (context, i) => CheckboxListTile( title: Text(todos[i].title), value: todos[i].completed, onChanged: (_) => ref.read(todoProvider.notifier).toggle(i), ), ); }✅ 优势:即使在
showDialog或静态方法中也能访问状态!
dependencies: flutter_bloc: ^8.1.0// todo_bloc.dart class TodoBloc extends Bloc<TodoEvent, TodoState> { final List<Todo> _todos = []; TodoBloc() : super(TodoInitial()) { on<AddTodo>((event, emit) { _todos.add(Todo(event.title)); emit(TodoLoaded(_todos)); }); } }⚠️ 编写量较大,但逻辑极其清晰。
| 方案 | 学习成本 | 适用场景 | 是否依赖 Context | 异步支持 |
|---|---|---|---|---|
| Provider | 低 | 中小型项目 | 是 | 一般 |
| Riverpod | 中 | 中大型项目 | 否 ✅ | 强 |
| Bloc | 高 | 复杂业务/团队协作 | 否 | 极强 |
GitHub 示例仓库:github.com/yourname/flutter-state-compare
欢迎在评论区讨论你用的状态管理方案!