Flutter MVVM架构插件simple_mvvm的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter MVVM架构插件simple_mvvm的使用

简介

Simple MVVM 是一个简洁且强大的状态管理库,它将MVVM结构与Flutter框架中的InheritedWidget相结合。该库允许你在Flutter应用中更方便地管理状态。

特性

  • 纯FlutterViewModelProvidersInheritedWidgets,因此你可以通过Flutter框架内置的方法访问它们。
  • 易于模型使用ViewModelProvider 提供了你的模型到其子部件,所以你通常不需要添加额外的代码来访问模型。
  • 无冗余:整个库只有60行Dart代码,没有任何外部依赖。

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  simple_mvvm: ^版本号

然后运行 flutter pub get 来安装依赖。

示例代码

以下是 simple_mvvm 的完整示例代码。

1. 创建 ViewModel

首先,创建一个 ViewModel 类。这个类是一个 State 对象,并引入了一个 InheritedWidget 到Widget树中。在这个类中,你可以放置业务逻辑和状态属性。

import 'package:simple_mvvm/simple_mvvm.dart';
import 'package:flutter/material.dart';

class HomeViewModel extends ViewModel<HomeViewModel> {
  static HomeViewModel of_(BuildContext context) => getModel<HomeViewModel>(context);

  final String title = 'Home';

  ValueNotifier<int> counter = ValueNotifier(0);

  void incrementCounter() {
    setState(() {
      counter.value++;
    });
  }

  [@override](/user/override)
  void initState() {
    debugPrint('Initialize');
    super.initState();
  }

  [@override](/user/override)
  void dispose() {
    debugPrint('Dispose');
    super.dispose();
  }
}

2. 创建 ViewModelBuilder

接下来,创建一个 ViewModelBuilder 类。这个类是一个 StatefulWidget,它会包含上述的 ViewModel

class HomeViewModelBuilder extends ViewModelBuilder<HomeViewModel> {
  const HomeViewModelBuilder({
    super.key,
    required super.builder,
  });

  [@override](/user/override)
  State<StatefulWidget> createState() => HomeViewModel();
}

3. 使用 ViewModelBuilder

最后,在你的应用中使用 ViewModelBuilder。你可以在任何地方访问 ViewModel

import 'package:simple_mvvm/simple_mvvm.dart';
import 'package:example/two.dart';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Simple MVVM',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomeView(),
    );
  }
}

class HomeView extends StatelessWidget {
  const HomeView({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return HomeViewModelBuilder(
      builder: (context, model) {
        return Scaffold(
          appBar: AppBar(
            title: Text(model.title),
          ),
          body: Stack(
            children: [
              Center(
                child: Padding(
                  padding: const EdgeInsets.all(24.0),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      ValueListenableBuilder(
                          valueListenable: model.counter,
                          builder: (context, value, child) => Row(
                                children: [
                                  const Text('ValueListenableBuilder: '),
                                  const SizedBox(width: 8),
                                  Text(value.toString()),
                                ],
                              )),
                      const SeparatedCounter(),
                      const ModelWidgetCounter(),
                      const SizedBox(height: 16),
                      ElevatedButton(
                        onPressed: model.isLoading
                            ? () {}
                            : () async {
                                HomeViewModel().of(context).incrementCounterWithSetState();
                                model.setLoading(false);
                              },
                        child: const Text('Increment using setState'),
                      ),
                      ElevatedButton(
                        onPressed: model.isLoading
                            ? () {}
                            : () {
                                model.incrementCounterWithValueNotifier();
                              },
                        child: const Text('Increment using ValueNotifier'),
                      )
                    ],
                  ),
                ),
              ),
              if (model.isLoading) const ColoredBox(color: Colors.black12, child: Center(child: CircularProgressIndicator()))
            ],
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => const ScreenTwoView(),
                ),
              );
            },
            child: const Icon(Icons.navigate_next),
          ),
        );
      },
    );
  }
}

class SeparatedCounter extends StatelessWidget {
  const SeparatedCounter({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Row(
      children: [
        const Text('SeparatedCounter: '),
        const SizedBox(width: 8),
        Text(HomeViewModel().of(context).counter.value.toString()),
      ],
    );
  }
}

class ModelWidgetCounter extends StatelessWidget {
  const ModelWidgetCounter({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return ModelWidget<HomeViewModel>(builder: (context, model) {
      return Row(
        children: [
          const Text('ModelWidgetCounter: '),
          const SizedBox(width: 8),
          Text(model.counter.value.toString()),
        ],
      );
    });
  }
}

更多关于Flutter MVVM架构插件simple_mvvm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter MVVM架构插件simple_mvvm的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用simple_mvvm插件来实现MVVM架构的一个基本示例。simple_mvvm插件帮助你将应用逻辑分离到Model、View、ViewModel中,从而使代码更加模块化和易于维护。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加simple_mvvm的依赖:

dependencies:
  flutter:
    sdk: flutter
  simple_mvvm: ^最新版本号  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

2. 创建Model

Model类通常用于定义应用的数据结构。例如,我们创建一个简单的User模型:

// models/user.dart
class User {
  final String name;
  final int age;

  User({required this.name, required this.age});

  // 可以添加一些方法来处理数据
  String getGreeting() {
    return "Hello, my name is $name and I am $age years old.";
  }
}

3. 创建ViewModel

ViewModel类负责处理业务逻辑和状态管理。我们创建一个UserViewModel来处理与用户相关的逻辑:

// viewmodels/user_view_model.dart
import 'package:simple_mvvm/simple_mvvm.dart';
import 'package:flutter/material.dart';
import 'models/user.dart';

class UserViewModel extends BaseViewModel<User> {
  User? _user;

  User? get user => _user;

  void fetchUser(User user) {
    _user = user;
    notifyListeners();  // 通知视图更新
  }
}

4. 创建View

View类通常是Widget,它负责展示数据并与用户进行交互。我们将创建一个简单的界面来展示用户信息:

// views/user_view.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'viewmodels/user_view_model.dart';
import 'models/user.dart';

class UserView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('User Information'),
      ),
      body: ChangeNotifierProvider<UserViewModel>(
        create: (_) => UserViewModel(),
        child: Consumer<UserViewModel>(
          builder: (context, model, child) => Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text('Name: ${model.user?.name ?? 'Loading...'}'),
                Text('Age: ${model.user?.age ?? 'Loading...'}'),
                Text('Greeting: ${model.user?.getGreeting() ?? 'Loading...'}'),
                ElevatedButton(
                  onPressed: () {
                    model.fetchUser(User(name: 'John Doe', age: 30));
                  },
                  child: Text('Fetch User'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

5. 主应用入口

最后,我们在main.dart中引入并展示UserView

// main.dart
import 'package:flutter/material.dart';
import 'views/user_view.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter MVVM Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: UserView(),
    );
  }
}

总结

上述代码展示了如何在Flutter中使用simple_mvvm插件实现一个简单的MVVM架构。这个示例包括了Model、ViewModel和View的基本实现,并通过Provider库来管理ViewModel的生命周期和状态更新。你可以根据需要扩展和修改这个示例,以适应更复杂的应用场景。

回到顶部