Flutter插件fluvvm的介绍与使用

Flutter插件fluvvm的介绍与使用

简介

Fluvvm 是一个轻量级库,用于从使用 providerMVVM 架构的 Flutter 应用程序中移除一些样板代码。此外,它还包括一个 NetworkRequest 类,使得网络请求变得简单易用。

为什么需要

我真的很享受使用 Flutter 和名为 provider 的惊人库,以及我最喜欢的架构 MVVM。然而,我发现自己一遍又一遍地编写相同的代码,并且 MVVM 模式并不是默认提供的。因此,我决定创建一个库来移除一些样板代码,并使网络、业务和 UI 层之间的界限更加清晰。

如何使用

1. 创建一个 Repository

class MyRepository {
  String baseUrl = 'https://example.com';
  String path = '/api/v1/data';

  late NetworkRequest fetchRequest = NetworkRequest(
    baseUrl: baseUrl,
    path: path,
    query: {'id': '1'},
  );

  Future<Map<String, dynamic>> store(Object data) async {
    try {
      final request = NetworkRequest(
        baseUrl: baseUrl,
        path: path,
        method: NetworkMethod.post,
      );
      return await request.fire(body: data);
    } catch (e) {
      rethrow;
    }
  }
}

2. 创建一个 ViewModel 并包含 FluvvmState 和 FluvvmIntent

class MyViewmodel extends Viewmodel<ExampleState, ExampleIntent> {
  final _repository = ExampleRepository();

  List<Object> get content => _content;
  List<Object> _content = [];

  @override
  void onBound() {
    setState(ExampleState.loading);
    unawaited(_fetchData());
  }

  @override
  void raiseIntent(ExampleIntent intent, {Object? data}) {
    switch (intent) {
      case ExampleIntent.fetchData:
        setState(ExampleState.loading);
        unawaited(_fetchData());
        break;
      case ExampleIntent.storeData:
        setState(ExampleState.loading);
        unawaited(_storeData(data));
        break;
      case ExampleIntent.navigateToWidget:
        // 导航到新的小部件并传递数据(如果需要)。
        break;
    }
  }

  Future<void> _fetchData() async {
    try {
      final map = await _repository.fetchRequest.fire();
      _content = _modifyDataBeforeServingToWidget(map);
      setState(ExampleState.content);
    } catch (e) {
      setState(ExampleState.error);
    }
  }

  Future<void> _storeData(Object? data) async {
    final thisData = data;
    if (thisData == null) {
      setState(ExampleState.error);
      return;
    }

    try {
      final map = await _repository.store(thisData);
      _modifyDataBeforeServingToWidget(map);
      setState(ExampleState.content);
    } catch (e) {
      setState(ExampleState.error);
    }
  }

  List<Object> _modifyDataBeforeServingToWidget(Map map) {
    return [];
  }
}

enum ExampleState implements FluvvmState {
  loading,
  content,
  error;
}

enum ExampleIntent with FluvvmIntent {
  fetchData,
  storeData,
  navigateToWidget,
}

3. 创建一个继承自 NotifiedWidget 的 Widget

class MyWidget extends NotifiedWidget<ExampleViewmodel> {
  const MyWidget({super.key, required super.viewmodel});

  @override
  Widget buildOnNotified(BuildContext context, ExampleViewmodel viewmodel) {
    return switch (viewmodel.state) {
      ExampleState.loading => const Center(child: CircularProgressIndicator()),
      ExampleState.content => CustomScrollView(
          slivers: [
            const SliverAppBar(
              title: Text('MyWidget'),
            ),
            SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) => ListTile(
                  title: Text(viewmodel.content[index].toString()),
                  onTap: () => viewmodel.raiseIntent(
                    ExampleIntent.storeData,
                    data: {'newData': index},
                  ),
                ),
                childCount: viewmodel.content.length,
              ),
            ),
          ],
        ),
      ExampleState.error => const Center(child: Text('Error'))
    };
  }
}

NetworkRequest

GET 请求

/// 简单的 GET 请求。
Future<Map<String, dynamic>> get(
  String id,
  Map<String, String>? headers,
) async {
  try {
    final request = NetworkRequest(
      baseUrl: 'https://example.com',
      path: '/api/v1/data',
      query: {'id': id},
    );
    return await request.fire(headers: headers);
  } catch (e) {
    rethrow;
  }
}

/// 带有映射的简单 GET 请求。
Future<MyResponseModel> getWithMap(String id) async {
  try {
    final request = NetworkRequest(
      baseUrl: 'https://example.com',
      path: '/api/v1/data',
      query: {'id': id},
    );
    return await request.fireAndMap(MyResponseModel.fromJson);
  } catch (e) {
    rethrow;
  }
}

POST 请求

Future<Map<String, dynamic>> post(Object data) async {
  try {
    final request = NetworkRequest(
      baseUrl: 'https://example.com',
      path: '/api/v1/data',
      method: NetworkMethod.post,
    );
    return await request.fire(body: data);
  } catch (e) {
    rethrow;
  }
}

PUT 请求

Future<Map<String, dynamic>> put(Object data) async {
  try {
    final request = NetworkRequest(
      baseUrl: 'https://example.com',
      path: '/api/v1/data',
      method: NetworkMethod.put,
    );
    return await request.fire(body: data);
  } catch (e) {
    rethrow;
  }
}

DELETE 请求

/// 简单的 DELETE 请求。
Future<Map<String, dynamic>> delete(String id, Object? data) async {
  try {
    final request = NetworkRequest(
      baseUrl: 'https://example.com',
      path: '/api/v1/data',
      method: NetworkMethod.delete,
      query: {'id': id},
    );
    return await request.fire(body: data);
  } catch (e) {
    rethrow;
  }
}

更多关于Flutter插件fluvvm的介绍与使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


在Flutter中,如果你遇到了一个未定义的插件(例如 fluvvm),这通常意味着该插件尚未在Flutter的官方插件库中注册,或者它可能是一个私有或第三方插件。由于我无法访问到所有第三方插件的具体实现,以下是一些通用的步骤和示例代码,展示如何在Flutter项目中集成和使用一个自定义或第三方插件。

步骤 1: 添加插件依赖

首先,你需要确保该插件已经发布到了某个包管理器(如pub.dev,或者私有包管理器)。如果它是一个私有包,你需要配置你的pubspec.yaml文件以访问该私有源。

假设fluvvm插件已经发布在pub.dev上(实际情况中需要替换为正确的包名和版本),你可以在pubspec.yaml中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  fluvvm: ^x.y.z  # 替换为实际的版本号

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

步骤 2: 导入插件

在你的Dart文件中,导入该插件:

import 'package:fluvvm/fluvvm.dart';

步骤 3: 使用插件功能

由于fluvvm的具体API和功能未知,我将提供一个假设性的使用案例。假设fluvvm提供了一个用于设备信息获取的简单功能。

import 'package:flutter/material.dart';
import 'package:fluvvm/fluvvm.dart'; // 假设的导入路径

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Fluvvm Demo'),
        ),
        body: Center(
          child: FutureBuilder<String>(
            future: Fluvvm.getDeviceInfo(), // 假设Fluvvm有一个静态方法叫getDeviceInfo
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else {
                  return Text('Device Info: ${snapshot.data}');
                }
              } else {
                return CircularProgressIndicator();
              }
            },
          ),
        ),
      ),
    );
  }
}

在这个例子中,我们假设Fluvvm类有一个静态方法getDeviceInfo(),该方法返回一个Future<String>,该字符串包含了设备信息。FutureBuilder用于异步获取数据并在UI中显示结果或错误。

注意

  • 如果fluvvm不是一个公开的插件,你可能需要从其他来源获取它,比如从私有Git仓库克隆。
  • 确保你遵循插件作者提供的安装和使用指南,因为第三方插件可能有特定的集成步骤或配置要求。
  • 如果插件未定义或不存在,你可能需要联系插件的开发者或查找其他替代方案。

由于fluvvm是一个假设的插件名称,上述代码仅为示例用途,实际使用时需要根据真实的插件API进行调整。

回到顶部