view_model
npx skills add https://github.com/lwj1994/flutter_view_model --skill view_model
Agent 安装分布
Skill 文档
view_model Skill
This skill provides comprehensive instructions for using the view_model state management library in Flutter. It focuses on architecture, reactivity, and lifecycle management.
æ ¸å¿è®¾è®¡å²å¦ (Core Philosophy)
view_model æ¯ä¸ä¸ªåºäº ç±»åé® (Type-keyed) å å¼ç¨è®¡æ° (Reference Counting) çç¶æç®¡çç³»ç».
- èªå¨çå½å¨æ: ViewModel çåæ´»åå³äºæ¯å¦ææ´»è·ç Bindingã
- è·¨ Context èªç±: å¨ä»»ä½æ··å
¥äº
ViewModelBindingçç±»ä¸é½å¯ä»¥è®¿é® ViewModelï¼æ éBuildContextã - 髿§è½: èªå¨å¤ç æå/æ¢å¤ é»è¾ï¼ä¸å¯è§æ¶ä¸å·æ°ã
1. æ ¸å¿ Mixins
with ViewModel
ç¨äºå®ä¹å管å®ä¾ã
- æä¾
onCreate,onBind,onUnbind,onDisposeé©åã - 使ç¨
notifyListeners()æupdate(() => ...)触åéç¥ã - å¯éè¿
viewModelBinding访é®å ¶ä»ä¾èµã - 使ç¨
addDispose(callback)æ³¨åæ¸ çé»è¾ã
with ViewModelBinding
ç¨äºè®¿é® ViewModels (Binding Host)ã
- å¨ Widget ä¸é常使ç¨
ViewModelStateMixinæViewModelStatelessMixinã - æä¾
viewModelBinding.watch()(ååºå¼) åviewModelBinding.read()(éååºå¼)ã
2. å®ä¹ ViewModelSpec
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 å
±äº«åä¸å®ä¾
);
3. Widget éæ
å¨ StatefulWidget ä¸
class MyPage extends StatefulWidget { ... }
class _MyPageState extends State<MyPage> with ViewModelStateMixin {
late final vm = viewModelBinding.watch(counterSpec);
Widget build(BuildContext context) {
return Text(vm.count.toString());
}
}
å¨ StatelessWidget ä¸
class MyWidget extends StatelessWidget with ViewModelStatelessMixin {
late final vm = viewModelBinding.watch(counterSpec);
Widget build(BuildContext context) => Text(vm.count.toString());
}
4. viewModelBinding å¸¸ç¨æ¥å£
| æ¹æ³ | 说æ |
|---|---|
watch(spec) |
å建/è·åå¹¶çå¬ãUI ééç¥å·æ°ã |
read(spec) |
å建/è·åä½ä¸çå¬ã常ç¨äºäºä»¶åè°ã |
watchCached<T>(key: ...) |
寻æ¾å·²åå¨çå®ä¾å¹¶çå¬ãè¥æ 忥éã |
readCached<T>(key: ...) |
寻æ¾å·²åå¨çå®ä¾ä½ä¸çå¬ã |
listenState(spec, onChanged: ...) |
çå¬ StateViewModel ç宿´ç¶æååã |
listenStateSelect(spec, selector: ..., onChanged: ...) |
é对æ§å°çå¬æä¸ªåæ®µã |
recycle(vm) |
强å¶éæ¯å®ä¾ï¼è§£ç»ææè¿æ¥ã |
5. ç¶æç®¡çè¿é¶
StateViewModel<T>
ç¨äºä¸å¯åç¶æã
class CounterViewModel extends StateViewModel<CounterState> {
CounterViewModel() : super(state: const CounterState());
void inc() => setState(state.copyWith(count: state.count + 1));
}
ç»ç²åº¦æ´æ°
ä½¿ç¨ StateViewModelValueWatcher åªå¨ç¹å®å段ååæ¶ rebuildã
6. æå/æ¢å¤ (Pause / Resume)
为äºè®©èªå¨æåçæï¼å¿
é¡»å¨ MaterialApp 䏿³¨å ViewModel.routeObserverã
MaterialApp(
navigatorObservers: [ViewModel.routeObserver],
...
)
7. èªå¨æµè¯ (Testing)
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(); // éæ¯å¹¶è§£ç»
});
8. 代ç çæ (Code Generation)
ä½¿ç¨ @GenSpec å¯ä»¥èªå¨çæ ViewModelSpec 代ç ï¼åå°æ ·æ¿ä»£ç ã
()
class CounterViewModel with ViewModel { ... }
çæçæä»¶å°å
å« counterViewModelSpecã
9. æä½³å®è·µ
- ä¾èµæ³¨å
¥: å¨ ViewModel å
é¨ç´æ¥ä½¿ç¨
viewModelBinding.read(otherSpec)è·åä¾èµã - æ¸
ç: æ°¸è¿ä¼å
使ç¨
addDispose()æ³¨åæ¸ çåè°ï¼èéæå¨è¦ådispose()ã - åä¾: 对å
¨å±ç¶æï¼å¦ Auth, Configï¼ä½¿ç¨
aliveForever: trueã - æ§è½: å¨
ListViewç Item ä¸ï¼å¦æåªæ¯ä¸ºäºè·åæ°æ®èä¸æææ´ä¸ª Item éå ¨å±ç¶æå·æ°ï¼ä¼å 使ç¨readã - 代ç çæ: é
å
view_model_annotationåview_model_generator使ç¨@GenSpecåå°æ ·æ¿ä»£ç ã