Flutter MVVM架构下如何无需重建等操作更新整个ViewModel数据
实现无需手动重建的Flutter MVVM ViewModel监听方案
核心思路
通过Flutter原生的ChangeNotifier实现ViewModel的变化通知,结合自定义InheritedNotifier(继承自InheritedWidget)让Widget自动感知ViewModel的整体变化,完全满足你的需求:无需手动调用重建方法、不用Stream/Future Builder、无外部依赖。
步骤1:让ViewModel继承ChangeNotifier
给ViewModel添加变化通知能力,当ViewModel整体数据更新时调用notifyListeners()触发更新:
class MyViewModel extends ChangeNotifier { // 示例业务数据 String _pageTitle = "初始页面标题"; int _dataCount = 0; // 暴露只读 getter String get pageTitle => _pageTitle; int get dataCount => _dataCount; // 更新ViewModel整体数据的方法(根据业务需求自定义) void refreshViewModel(String newTitle, int newCount) { _pageTitle = newTitle; _dataCount = newCount; // 通知所有依赖的Widget自动更新 notifyListeners(); } }
步骤2:自定义ViewModelProvider(基于InheritedNotifier)
封装一个继承自InheritedNotifier的Provider类,用于在Widget树中传递ViewModel,并自动监听其变化:
class ViewModelProvider<T extends ChangeNotifier> extends InheritedNotifier<T> { final T viewModel; const ViewModelProvider({ super.key, required this.viewModel, required super.child, }) : super(notifier: viewModel); // 静态工具方法,方便子Widget快速获取ViewModel static T? of<T extends ChangeNotifier>(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<ViewModelProvider<T>>()?.viewModel; } }
步骤3:在Widget中使用ViewModel
子Widget通过ViewModelProvider.of()获取ViewModel,当ViewModel调用notifyListeners()时,该Widget会自动重建,无需手动触发:
class HomeView extends StatelessWidget { const HomeView({super.key}); @override Widget build(BuildContext context) { // 获取ViewModel,自动建立依赖关系 final viewModel = ViewModelProvider.of<MyViewModel>(context)!; return Scaffold( appBar: AppBar(title: Text(viewModel.pageTitle)), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("当前计数: ${viewModel.dataCount}", style: const TextStyle(fontSize: 20)), const SizedBox(height: 20), ElevatedButton( onPressed: () { // 更新ViewModel数据,无需手动调用setState或rebuild viewModel.refreshViewModel("更新后的标题", viewModel.dataCount + 1); }, child: const Text("更新数据"), ), ], ), ), ); } }
步骤4:在顶层注入ViewModel
在应用入口处将ViewModel注入到Widget树中:
void main() { runApp( ViewModelProvider( viewModel: MyViewModel(), child: const MaterialApp( home: HomeView(), ), ), ); }
为什么之前的InheritedWidget没生效?
多数情况是因为你没有将InheritedWidget和变化监听机制结合:普通的InheritedWidget只会在自身updateShouldNotify返回true时触发更新,而结合ChangeNotifier和InheritedNotifier后,ViewModel的变化会自动触发InheritedWidget的更新通知,无需手动实现updateShouldNotify逻辑。
内容的提问来源于stack exchange,提问作者Rafaelo Vandov
相关产品推荐
相关产品推荐

