V2EX 10月13日 02:02
自研ViewModel库,简化Flutter状态管理
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

对于Riverpod繁琐的使用方式感到困扰,作者自研了一个名为`view_model`的Flutter状态管理库。该库的核心理念是简单纯粹,仅提供ViewModel概念,无额外复杂功能。通过ViewModel和ViewModelFactory,开发者可以轻松创建和管理应用状态。使用`watchViewModel`方法,可以直接在Widget中获取ViewModel实例,并在数据更新时自动触发UI重绘。虽然它没有提供细粒度更新,但作者认为Flutter的Widget diff机制已足够高效,无需过度优化。对于需要局部高频更新的场景,可以结合`ValueNotifierBuilder`实现。

💡 **核心理念:纯粹与简单** - `view_model`库旨在提供一个极其简单且纯粹的状态管理方案,专注于ViewModel这一核心概念,避免了其他状态管理库中可能出现的“花里胡哨”的功能,使得开发者能够更专注于业务逻辑而非复杂的工具链。

🚀 **易于使用与集成** - 通过`ViewModel`和`ViewModelFactory`的简单模式,开发者可以轻松实例化和管理ViewModel。`watchViewModel`方法允许在Widget的`initState`中便捷地获取ViewModel实例,并在数据变化时自动更新UI,大大简化了状态管理的代码量。

⚙️ **高效的UI更新机制** - 该库认为Flutter自身的Widget diffing机制已足够高效,即使频繁调用`setState`对帧率影响也微乎其微。因此,它不提供细粒度更新,而是依赖Widget的固有渲染效率。对于确实需要局部高频更新的场景,建议结合`ValueNotifierBuilder`进行实现,保持了API的简洁性。

📦 **可扩展性与资源管理** - `ViewModel`基类提供了`dispose`方法,允许开发者在ViewModel被销毁时进行必要的资源清理,例如关闭StreamControllers等,确保应用的稳定性和内存管理。

被 riverpod 繁琐和侵入式的使用方式困扰许久后,自己重新造了个轮子。https://pub.dev/packages/view_model

优点是使用简单, 非常纯粹, 只是 view_model 没有其他花里花哨的概念。

import 'package:view_model/view_model.dart';import 'package:flutter/foundation.dart'; // For debugPrintclass MySimpleViewModel extends ViewModel {  String _message = "Initial Message";  int _counter = 0;  String get message => _message;  int get counter => _counter;  void updateMessage(String newMessage) {    _message = newMessage;    notifyListeners(); // 通知监听者数据已更新  }  void incrementCounter() {    _counter++;    notifyListeners(); // 通知监听者数据已更新  }  @override  void dispose() {    // 在此清理资源,例如关闭 StreamControllers 等    debugPrint('MySimpleViewModel disposed');    super.dispose();  }}

ViewModelFactory 负责实例化 ViewModel 。每个 ViewModel 类型通常 需要一个对应的 Factory 。

import 'package:view_model/view_model.dart';// 假设 MySimpleViewModel 已如上定义class MySimpleViewModelFactory with ViewModelFactory<MySimpleViewModel> {  @override  MySimpleViewModel build() {    // 返回一个新的 MySimpleViewModel 实例    return MySimpleViewModel();  }}

通过 watchViewModel 直接在 State 中使用.

class _MyPageState extends State<MyPage>    with ViewModelStateMixin<MyPage> {  // 1. 混入 Mixin  late final MySimpleViewModel simpleVM;  @override  void initState() {    super.initState();    // 2. 在 initState 中获取 ViewModel    // 当 MyPage 第一次构建时,MySimpleViewModelFactory 的 build() 方法会被调用来创建实例。    // 当 MyPage 被销毁时,如果此 viewModel 没有其他监听者,它也会被销毁。    simpleVM =        watchViewModel<MySimpleViewModel>(factory: MySimpleViewModelFactory());  }        @override  Widget build(BuildContext context) {    // 直接使用. simpleVM 数据更新后,会自动 setState    Tetx(simpleVM.xxx);  }

缺点是没有颗粒度更新,但我认为这其实不算缺点,这不是状态管理该做的事,但 riverpod bloc signal 似乎都对这个很在意,Widget 本身的 diff 已经足够高效, 就算每秒 setState 对帧率的影响也微乎其微,因为底层的 Render 没变,Widget 只是配置而已。 如果你真的需要频繁更新某个 局部 Widget ,那你应该使用 ValueNotitifierBuilder : https://github.com/lwj1994/flutter_view_model/issues/13

完整的文档: https://github.com/lwj1994/flutter_view_model/blob/main/packages/view_model/README_ZH.md

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Flutter 状态管理 ViewModel Riverpod 自研库 State Management Custom Library Dart
相关文章