원클릭으로
view-model
Guide for building and using ViewModels with reference-counted lifecycle and reactive binding in Flutter.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Guide for building and using ViewModels with reference-counted lifecycle and reactive binding in Flutter.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Build or refactor Flutter functional modules and state management with the view_model package, including module-to-module dependency injection, ViewModel/ViewModelBinding mixins, ViewModelSpec sharing, watch/read semantics, lifecycle, pause-resume, testing, and code generation.
Workflow for publishing view_model packages (annotation, generator, view_model) in the correct order.
| name | view_model |
| description | Guide for building and using ViewModels with reference-counted lifecycle and reactive binding in Flutter. |
| mintlify-proj | flutter-view-model |
This skill provides comprehensive instructions for using the view_model state management library in Flutter. It focuses on architecture, reactivity, and lifecycle management.
view_model 是一个基于 类型键 (Type-keyed) 和 引用计数 (Reference Counting) 的状态管理系统.
ViewModelBinding 的类中都可以访问 ViewModel,无需 BuildContext。with ViewModel用于定义受管实例。
onCreate, onBind, onUnbind, onDispose 钩子。notifyListeners() 或 update(() => ...) 触发通知。viewModelBinding 访问其他依赖。addDispose(callback) 注册清理逻辑。with ViewModelBinding用于访问 ViewModels (Binding Host)。
ViewModelStateMixin 或 ViewModelStatelessMixin。viewModelBinding.watch() (响应式) 和 viewModelBinding.read() (非响应式)。ViewModelSpec 是 ViewModel 的工厂定义。
// 1. 无参数,单例共享
final authSpec = ViewModelSpec<AuthViewModel>(
builder: () => AuthViewModel(),
key: 'global_auth',
aliveForever: true, // 全局常驻
);
// 2. 带参数,按需创建
final userSpec = ViewModelSpec.arg<UserViewModel, String>(
builder: (id) => UserViewModel(id),
key: (id) => 'user-$id', // 相同 ID 共享同一实例
);
class MyPage extends StatefulWidget { ... }
class _MyPageState extends State<MyPage> with ViewModelStateMixin {
late final vm = viewModelBinding.watch(counterSpec);
@override
Widget build(BuildContext context) {
return Text(vm.count.toString());
}
}
class MyWidget extends StatelessWidget with ViewModelStatelessMixin {
late final vm = viewModelBinding.watch(counterSpec);
@override
Widget build(BuildContext context) => Text(vm.count.toString());
}
| 方法 | 说明 |
|---|---|
watch(spec) | 创建/获取并监听。UI 随通知刷新。 |
read(spec) | 创建/获取但不监听。常用于事件回调。 |
watchCached<T>(key: ...) | 寻找已存在的实例并监听。若无则报错。 |
readCached<T>(key: ...) | 寻找已存在的实例但不监听。 |
listenState(spec, onChanged: ...) | 监听 StateViewModel 的完整状态变化。 |
listenStateSelect(spec, selector: ..., onChanged: ...) | 针对性地监听某个字段。 |
recycle(vm) | 强制销毁实例,解绑所有连接。 |
StateViewModel<T>用于不可变状态。
class CounterViewModel extends StateViewModel<CounterState> {
CounterViewModel() : super(state: const CounterState());
void inc() => setState(state.copyWith(count: state.count + 1));
}
使用 StateViewModelValueWatcher 只在特定字段变化时 rebuild。
为了让自动暂停生效,必须在 MaterialApp 中注册 ViewModel.routeObserver。
MaterialApp(
navigatorObservers: [ViewModel.routeObserver],
...
)
view_model 使单元测试变得非常简单,因为它不强依赖于 BuildContext。
test('counter increments', () {
final binding = ViewModelBinding(); // 创建测试用的 Binding
final vm = binding.watch(counterSpec);
expect(vm.count, 0);
vm.increment();
expect(vm.count, 1);
binding.dispose(); // 销毁并解绑
});
使用 @GenSpec 可以自动生成 ViewModelSpec 代码,减少样板代码。
@GenSpec()
class CounterViewModel with ViewModel { ... }
生成的文件将包含 counterViewModelSpec。
viewModelBinding.read(otherSpec) 获取依赖。addDispose() 注册清理回调,而非手动覆写 dispose()。aliveForever: true。ListView 的 Item 中,如果只是为了获取数据而不期望整个 Item 随全局状态刷新,优先使用 read。view_model_annotation 和 view_model_generator 使用 @GenSpec 减少样板代码。