Flutter数据查询插件query_client的使用

Flutter数据查询插件query_client的使用

query_client 是一个类似 React Hook 的工具,专门为 Flutter 设计。它可以帮助开发者轻松处理 API 请求、自动更新 UI、实现无限加载(分页加载)以及本地数据的即时变更。


特性

1. 简单的API请求

query_client 提供了简单的 API 请求方式,只需传入一个异步函数即可完成数据获取。

// 定义 QueryClient
final _queryClient = QueryClient<bool>(
  ({data, dataList}) async {
    // 模拟延迟
    await Future.delayed(Duration(seconds: 1));
    return true;
  },
);

// 在 Widget 中使用 FutureBuilder
Widget build() {
  return FutureBuilder(
    future: _queryClient.future, // 使用 QueryClient 的 future 属性
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        return Text("just work");
      }
      return Text("Loading...");
    },
  );
}

2. 自动更新UI

通过 onUpdate 回调,可以实现在数据变化时自动更新 UI。

final _queryClient = QueryClient<bool>(
  ({data, dataList}) async {
    await Future.delayed(Duration(seconds: 1));
    return true;
  },
  onUpdate: () {
    // 如果需要自动更新 UI,可以调用 setState
    if (mounted) setState(() {});
  },
);

Widget build() {
  if (_queryClient.isLoading) {
    return Center(child: Text("Loading..."));
  }

  if (_queryClient.isError) {
    print("[MyWidget] error ${_queryClient.error}");
    return GestureDetector(
      child: Center(child: Text("🤕 Something went wrong! Tap to retry")),
      onTap: () {
        // 重试请求
        _queryClient.request();
      },
    );
  }

  return Center(child: Text("🎉 It works! ${_queryClient.data}"));
}

3. 无限加载(分页模式)

query_client 支持无限加载功能,可以通过 loadMore() 方法加载更多数据。

final _queryClient = QueryClient<bool>(
  ({data, dataList}) async {
    if (data != null) {
      // 使用上一次的数据来加载下一页
      await Future.delayed(Duration(seconds: 1));
    } else {
      await Future.delayed(Duration(seconds: 1));
    }
    return true;
  },
  onUpdate: () {
    if (mounted) setState(() {});
  },
);

Widget build() {
  if (_queryClient.isLoading) {
    return Center(child: Text("Loading..."));
  }

  if (_queryClient.isError) {
    print("[MyWidget] error ${_queryClient.error}");
    return GestureDetector(
      child: Center(child: Text("🤕 Something went wrong! Tap to retry")),
      onTap: () {
        // 重试请求
        _queryClient.request();
      },
    );
  }

  return GestureDetector(
    child: Center(
      child: Text("🎉 It works! ${_queryClient.data}. Tap to load more."),
    ),
    onTap: () {
      // 加载更多数据
      _queryClient.loadMore();
    },
  );
}

4. 数据变更(Mutate Data)

当需要对已加载的数据进行变更(如删除一条记录),可以使用 mutate() 方法。

final _queryClient = QueryClient<bool>(
  ({data, dataList}) async {
    if (data != null) {
      // 使用上一次的数据来加载下一页
      await Future.delayed(Duration(seconds: 1));
    } else {
      await Future.delayed(Duration(seconds: 1));
    }
    return true;
  },
  onUpdate: () {
    if (mounted) setState(() {});
  },
);

Widget build() {
  if (_queryClient.isLoading) {
    return Center(child: Text("Loading..."));
  }

  if (_queryClient.isError) {
    print("[MyWidget] error ${_queryClient.error}");
    return GestureDetector(
      child: Center(child: Text("🤕 Something went wrong! Tap to retry")),
      onTap: () {
        // 重试请求
        _queryClient.request();
      },
    );
  }

  final list = data.list;

  return GestureDetector(
    child: Column(
      children: list.map((x) {
        return GestureDetector(
          child: Text(x.name),
          onTap: () {
            // 删除该项
            _queryClient.mutate(({data, dataList}) {
              // 从列表中移除该数据
              final originIndex = data.list.indexWhere((y) => y.id == x.id);
              final origin = data.list.removeAt(originIndex);

              // 发送删除请求到服务器
              return Request.deleteItem(x.id)
                .then((res) {
                  // 成功则无需操作
                })
                .catchError((err) {
                  // 失败则将数据放回原位置
                  data.list.insert(originIndex, origin);
                  // 提示用户
                  Toast.show("🤕 Something went wrong! Try again!");
                });
            });
          },
        );
      }).toList(),
    ),
    onTap: () {
      // 加载更多数据
      _queryClient.loadMore();
    },
  );
}
1 回复

更多关于Flutter数据查询插件query_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


query_client 是一个用于在 Flutter 应用中简化数据查询和状态管理的插件。它通常用于与后端 API 进行交互,并管理查询的状态(如加载、成功、错误等)。query_client 的设计灵感来自于 React Query,它提供了一种简单且强大的方式来管理异步数据。

安装 query_client

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

dependencies:
  flutter:
    sdk: flutter
  query_client: ^0.1.0  # 请使用最新版本

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

基本用法

1. 创建 QueryClient

QueryClientquery_client 的核心类,它负责管理所有的查询。你可以在应用的顶层创建一个 QueryClient 实例,并将其提供给整个应用。

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

void main() {
  final queryClient = QueryClient();
  runApp(MyApp(queryClient: queryClient));
}

class MyApp extends StatelessWidget {
  final QueryClient queryClient;

  const MyApp({Key? key, required this.queryClient}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(queryClient: queryClient),
    );
  }
}

2. 使用 Query 进行数据查询

Queryquery_client 中用于执行数据查询的类。你可以使用 Query 来获取数据,并管理查询的状态。

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

class MyHomePage extends StatelessWidget {
  final QueryClient queryClient;

  const MyHomePage({Key? key, required this.queryClient}) : super(key: key);

  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 2)); // 模拟网络请求
    return 'Hello, Query Client!';
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Query Client Example'),
      ),
      body: Center(
        child: Query<String>(
          queryClient: queryClient,
          queryKey: 'exampleQuery',
          queryFn: fetchData,
          builder: (context, state) {
            if (state.isLoading) {
              return CircularProgressIndicator();
            } else if (state.hasError) {
              return Text('Error: ${state.error}');
            } else {
              return Text('Data: ${state.data}');
            }
          },
        ),
      ),
    );
  }
}

3. 使用 Mutation 进行数据更新

Mutationquery_client 中用于执行数据更新的类。你可以使用 Mutation 来提交数据,并管理更新的状态。

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

class MyHomePage extends StatelessWidget {
  final QueryClient queryClient;

  const MyHomePage({Key? key, required this.queryClient}) : super(key: key);

  Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 2)); // 模拟网络请求
    return 'Hello, Query Client!';
  }

  Future<void> updateData(String newData) async {
    await Future.delayed(Duration(seconds: 2)); // 模拟网络请求
    // 这里可以执行实际的更新操作
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Query Client Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Query<String>(
              queryClient: queryClient,
              queryKey: 'exampleQuery',
              queryFn: fetchData,
              builder: (context, state) {
                if (state.isLoading) {
                  return CircularProgressIndicator();
                } else if (state.hasError) {
                  return Text('Error: ${state.error}');
                } else {
                  return Text('Data: ${state.data}');
                }
              },
            ),
            Mutation<void, String>(
              queryClient: queryClient,
              mutationFn: updateData,
              builder: (context, mutate, state) {
                return ElevatedButton(
                  onPressed: () {
                    mutate('New Data');
                  },
                  child: state.isLoading
                      ? CircularProgressIndicator()
                      : Text('Update Data'),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!