Flutter代码生成插件riverpod_mutations_generator的使用

Flutter代码生成插件riverpod_mutations_generator的使用

你好!这是一个尝试填补由riverpod缺乏突变支持所留下的空白。详情可参见此问题

首先,导入riverpod_mutations_annotationriverpod_annotation

dependencies:
  riverpod: ^2.4.4 # 你的首选riverpod包
  riverpod_annotation: ^2.2.0  
  riverpod_mutations_annotation: ^1.0.0

dev_dependencies:
  build_runner: ^2.3.3
  riverpod_generator: ^2.3.5
  riverpod_mutations_generator: ^1.0.0

接下来,我们通过示例来展示如何使用riverpod_mutations_generator

示例代码

以下是一个完整的示例代码,展示了如何使用riverpod_mutations_generator

定义模型类

首先定义一个简单的Todo模型类:

class Todo {
  const Todo(this.id, this.todo);
  final int id;
  final String todo;
}

使用Riverpod Provider定义状态管理

接下来,在example.g.dart文件中生成代码,并在example.dart文件中使用这些代码:

import 'package:riverpod/riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:riverpod_mutations_annotation/riverpod_mutations_annotation.dart';

part 'example.g.dart';

@riverpod
class TodoList extends _$TodoList {
  @override
  FutureOr<List<Todo>> build() => [];

  @mutation
  Future<void> addTodo(Todo newTodo) async {
    // 模拟一些操作
    await Future.delayed(Duration.zero);
    // 将新项目加载到列表中
    state = AsyncData((await future)..add(newTodo));

    // 或者这样做,以让构建方法获取最新信息
    ref.invalidateSelf();
    await future;
  }

  @mutation
  Future<void> removeTodo({@mutationKey required int id}) async {
    // 模拟一些操作
    await Future.delayed(Duration.zero);

    // 从列表中移除项目
    state = AsyncData((await future)..removeWhere((e) => e.id == id));

    // 或者这样做,以让构建方法获取最新信息
    ref.invalidateSelf();
    await future;
  }
}

void example(AutoDisposeRef ref) {
  // 正常使用
  final todoList = ref.watch(todoListProvider);

  final addTodo = ref.watch(todoListProvider.addTodo);

  switch (addTodo) {
    case AddTodoMutationIdle():
      print('Idle/Initial');

    case AddTodoMutationLoading():
      print('Loading...');

    case AddTodoMutationSuccess():
      print('Success!');

    case AddTodoMutationFailure(:final error):
      print(error.toString());
  }

  addTodo(Todo(1, 'newTodo'));

  final removeTodo = ref.watch(todoListProvider.removeTodo(id: 1));

  // 用@mutationKey标记的参数已被删除,因为它现在存储在`removeTodo.params.id`对象中
  removeTodo();

  final int storedId = removeTodo.params.id;
}

在UI中使用

最后,在UI中使用这些突变方法:

return Consumer(
  builder: (context, ref, child) {
    // 正常的todo列表
    List<Todo> todos = ref.watch(todoListProvider);
    // 这里是有趣的部分
    AddTodoMutation addTodo = ref.watch(todoListProvider.addTodo);

    // 这将允许你多次跟踪同一个方法,就像一个家庭一样。
    // 注意:参数已被从`removeTodo()`中删除,如所示。
    // 这个特定值现在存储在`removeTodo.params.id`对象中
    RemoveTodoMutation removeTodo = ref.watch(todoListProvider.removeTodo(id: 4));

    return Row(
      children: [
        AddButton(
          // 调用Todo.addTodo方法
          // 如果当前正在加载,则禁用按钮
          onTap: addTodo is AddTodoMutationLoading ? null : () => addTodo(Todo()),
          // 显示侧面效果的状态
          trailing: switch (addTodo) {
            AddTodoMutationInitial() => Icon(Icons.circle),
            AddTodoMutationLoading() => CircularProgressIndicator(),
            AddTodoMutationSuccess() => Icon(Icons.check),
            AddTodoMutationFailure(:final error) => IconButton(Icons.info, onPressed: () => showErrorDialog(error)),
          },
        ),
        RemoveButton(
          // 注意,参数已被删除,因为它现在存储在`removeTodo.params.id`对象中
          onTap: removeTodo is RemoveTodoMutationLoading ? null : () => removeTodo(),
          // 显示侧面效果的状态
          trailing: switch (removeTodo) {
            RemoveTodoMutationInitial() => Icon(Icons.circle),
            RemoveTodoMutationLoading() => CircularProgressIndicator(),
            RemoveTodoMutationSuccess() => Icon(Icons.check),
            RemoveTodoMutationFailure(:final error) => IconButton(Icons.info, onPressed: () => showErrorDialog(error)),
          },
        );
      ],
    );
  },
);

更多关于Flutter代码生成插件riverpod_mutations_generator的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter代码生成插件riverpod_mutations_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 riverpod_mutations_generator Flutter 插件的代码示例。这个插件旨在自动生成与 Riverpod 状态管理相关的代码,特别是用于处理状态的变更(mutations)。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 riverpod_mutations_generator 及其相关依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_hooks: ^0.18.0
  flutter_riverpod: ^1.0.0

dev_dependencies:
  build_runner: ^2.1.4
  riverpod_generator: ^1.0.0
  riverpod_mutations_generator: ^0.4.0  # 确保使用最新版本

2. 创建状态类

假设我们有一个简单的用户状态类 UserState

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user_state.freezed.dart';

@freezed
class UserState with _$UserState {
  const factory UserState({
    required String name,
    required int age,
  }) = _UserState;

  factory UserState.initial() => UserState(name: '', age: 0);
}

为了使用 Freezed 生成不可变类和 copyWith 方法,你需要运行 flutter pub run build_runner build

3. 定义 Mutations

接下来,我们定义一些 mutations 来修改 UserState

import 'package:riverpod_mutations_generator/riverpod_mutations_generator.dart';
import 'user_state.dart';

part 'user_mutations.g.dart';

@Mutations<UserState>()
class UserMutations {
  UserMutations._();

  void setName(String name) => mutate((state) => state.copyWith(name: name));

  void setAge(int age) => mutate((state) => state.copyWith(age: age));
}

运行 flutter pub run build_runner build 来生成 user_mutations.g.dart 文件。

4. 设置 Riverpod Provider

使用生成的 mutations 设置一个 Riverpod provider:

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'user_mutations.g.dart';
import 'user_state.dart';

final userProvider = StateNotifierProvider<UserNotifier, UserState>(
  (ref) => UserNotifier(UserState.initial()),
);

class UserNotifier extends StateNotifier<UserState> {
  UserNotifier(UserState state) : super(state);

  void setName(String name) {
    state = UserMutations().setName(name)(state)!;
  }

  void setAge(int age) {
    state = UserMutations().setAge(age)(state)!;
  }
}

5. 在 UI 中使用 Provider

最后,在 Flutter UI 中使用这个 provider:

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'user_provider.dart';

void main() {
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}

class MyApp extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final userState = useProvider(userProvider.state);
    final userNotifier = useProvider(userProvider.notifier);

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('User Info')),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              TextField(
                decoration: InputDecoration(labelText: 'Name'),
                onChanged: (value) {
                  userNotifier.setName(value);
                },
              ),
              SizedBox(height: 16),
              TextField(
                decoration: InputDecoration(labelText: 'Age'),
                keyboardType: TextInputType.number,
                onChanged: (value) {
                  if (value.isNotEmpty) {
                    userNotifier.setAge(int.parse(value));
                  }
                },
              ),
              SizedBox(height: 16),
              Text('Name: ${userState.name}'),
              SizedBox(height: 8),
              Text('Age: ${userState.age}'),
            ],
          ),
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的用户界面,允许用户编辑用户的名字和年龄。这些变更通过 UserMutations 生成的方法应用到 UserState

希望这个示例能够帮助你理解如何使用 riverpod_mutations_generator 插件来简化 Flutter 应用中的状态管理。

回到顶部