V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lumyx
V2EX  ›  Flutter

最简单的状态管理库 view_model

  •  
  •   lumyx ·
    qwqwke · 1 天前 · 356 次点击

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

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

    import 'package:view_model/view_model.dart';
    import 'package:flutter/foundation.dart'; // For debugPrint
    
    class 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

    1 条回复    2025-10-13 02:00:57 +08:00
    Ditto8597
        1
    Ditto8597  
       20 小时 55 分钟前
    很好,用用
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2801 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 14:56 · PVG 22:56 · LAX 07:56 · JFK 10:56
    ♥ Do have faith in what you're doing.