小工具知识网

当前位置: 首页 > 行业知识 > flutter封装dio请求库,让我们做前端的同学可以轻松上手使用,仿照axios的使用封装

行业知识

flutter封装dio请求库,让我们做前端的同学可以轻松上手使用,仿照axios的使用封装

2026-11-07 14:38:43 来源:互联网转载

dio是一个非常强大的网络请求库,可以支持发送各种网络请求,就像axios一样灵活强大,但是官网没有做一个demo示例,所以前端同学使用起来还是有点费劲,所以就想在这里封装一下,方便前端同学使用。

官网地址:dio | Dart Package

我的flutter模板项目地址: GitHub - Sjj1024/flutter_windows: 使用flutter开发跨平台桌面软件的案例

添加依赖

在pubspec.yaml文件中添加所需要的第三方依赖库

dependencies:  flutter:    sdk: flutter  # The following adds the Cupertino Icons font to your application.  # Use with the CupertinoIcons class for iOS style icons.  cupertino_icons: ^1.0.2  get: ^4.6.6  dio: ^5.4.0

封装基础请求工具

在utils里面新建一个request.dart文件,专门用来做请求工具的,就像前端框架里面集成axios一样:统一初始化网络请求常见配置,实现请求拦截器、响应拦截器以及错误处理。

request.dart 代码: 

import 'package:dio/dio.dart';/// 请求方法:枚举类型enum DioMethod {  get,  post,  put,  delete,  patch,  head,}// 创建请求类:封装dioclass Request {  /// 单例模式  static Request? _instance;  // 工厂函数:执行初始化  factory Request() => _instance ?? Request._internal();  // 获取实例对象时,如果有实例对象就返回,没有就初始化  static Request? get instance => _instance ?? Request._internal();  /// Dio实例  static Dio _dio = Dio();  /// 初始化  Request._internal() {    // 初始化基本选项    BaseOptions options = BaseOptions(        baseUrl: 'http://你的服务器地址',        connectTimeout: const Duration(seconds: 5),        receiveTimeout: const Duration(seconds: 5));    _instance = this;    // 初始化dio    _dio = Dio(options);    // 添加拦截器    _dio.interceptors.add(InterceptorsWrapper(        onRequest: _onRequest, onResponse: _onResponse, onError: _onError));  }  /// 请求拦截器  void _onRequest(RequestOptions options, RequestInterceptorHandler handler) {    // 对非open的接口的请求参数全部增加userId    if (!options.path.contains("open")) {      options.queryParameters["userId"] = "xxx";    }    // 头部添加token    // options.headers["token"] = "xxx";    // 更多业务需求    handler.next(options);    // super.onRequest(options, handler);  }  /// 相应拦截器  void _onResponse(      Response response, ResponseInterceptorHandler handler) async {    // 请求成功是对数据做基本处理    if (response.statusCode == 200) {      // 处理成功的响应      // print("响应结果: $response");    } else {      // 处理异常结果      print("响应异常: $response");    }    handler.next(response);  }  /// 错误处理: 网络错误等  void _onError(DioException error, ErrorInterceptorHandler handler) {    handler.next(error);  }  /// 请求类:支持异步请求操作  Future request(    String path, {    DioMethod method = DioMethod.get,    Map? params,    dynamic data,    CancelToken? cancelToken,    Options? options,    ProgressCallback? onSendProgress,    ProgressCallback? onReceiveProgress,  }) async {    const _methodValues = {      DioMethod.get: 'get',      DioMethod.post: 'post',      DioMethod.put: 'put',      DioMethod.delete: 'delete',      DioMethod.patch: 'patch',      DioMethod.head: 'head'    };    // 默认配置选项    options ??= Options(method: _methodValues[method]);    try {      Response response;      // 开始发送请求      response = await _dio.request(path,          data: data,          queryParameters: params,          cancelToken: cancelToken,          options: options,          onSendProgress: onSendProgress,          onReceiveProgress: onReceiveProgress);      return response.data;    } on DioException catch (e) {      print("发送请求异常: $e");      rethrow;    }  }  /// 开启日志打印  /// 需要打印日志的接口在接口请求前 Request.instance?.openLog();  void openLog() {    _dio.interceptors        .add(LogInterceptor(responseHeader: false, responseBody: true));  }}

管理apis网络请求

然后创建一个apis文件夹,集成所有的apis网络请求,并在里面创建user.dart、goods.dart等文件,用于对不同的网络请求进行管理,这样就可以知道我们相关的网路请求放在哪里面。并且对返回的数据根据实际需求进行处理,如果数据的修改需要更新UI或者需要全局共享该数据

app.dart文件代码:

import '../utils/request.dart';// 创建一个关于user相关请求的对象class UserApi {  /// 单例模式  static UserApi? _instance;  // 工厂函数:初始化,默认会返回唯一的实例  factory UserApi() => _instance ?? UserApi._internal();  // 用户Api实例:当访问UserApi的时候,就相当于使用了get方法来获取实例对象,如果_instance存在就返回_instance,不存在就初始化  static UserApi? get instance => _instance ?? UserApi._internal();  /// 初始化  UserApi._internal() {    // 初始化基本选项  }  /// 获取权限列表  getUser() async {    /// 开启日志打印    Request.instance?.openLog();    /// 发起网络接口请求    var result = await Request().request('get_user', method: DioMethod.get);    // 返回数据    return result.data;  }  // 获取列表数据  getGoods() async {    var result = await Request().request("/game/gamemgnt",        method: DioMethod.post,        data: {"taskuuid": "queryprod", "splist": "66"});    // 返回数据    // print("getDetail:$result");    return result;  }  // 获取列表数据  getDetail() async {    var result = await Request().request("/game/gamemgnt",        method: DioMethod.post,        data: {"taskuuid": "queryprod", "splist": "66"});    // 返回数据    // print("getDetail:$result");    return result;  }}// 导出全局使用这一个实例final userApi = UserApi();

在组件页面使用

然后就可以到组件页面导入userApi给组件页面上使用,发送相应的网络请求了:

页面组件导入并发送请求获取数据,然后渲染:

import 'package:flutter/material.dart';import 'package:flutter_windows/apis/app.dart';class Lists extends StatefulWidget {  const Lists({super.key});  @override  State createState() => _ListsState();}class _ListsState extends State {  // 列表数据  List goods = [];  @override  void initState() {    // TODO: implement initState    super.initState();    // 获取商品列表    getGoods();  }  // 获取列表  getGoods() async {    var res = await userApi.getGoods();    var goodsData = res['response_data']['data'];    setState(() {      goods = goodsData;    });  }  // 动态列表组件  List _getListData() {    var tempList = goods.map((value) {      return Container(        decoration: BoxDecoration(            border: Border.all(                color: const Color.fromRGBO(233, 233, 233, 0.9), width: 1)),        child: Column(          children: [            Image.network(              value['skillurl'],              width: 100,              height: 200,            ),            const SizedBox(height: 12),            Text(              value['pordname'],              textAlign: TextAlign.center,              style: const TextStyle(fontSize: 20),            )          ],        ),      );    }); // ('xxx','xxx')    print("渲染的列表组件类型:${tempList.toList().runtimeType}");    return tempList.toList();  }  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text("产品列表"),      ),      body: GridView.count(        crossAxisSpacing: 10.0,        //水平子 Widget 之间间距        mainAxisSpacing: 10.0,        //垂直子 Widget 之间间距        padding: const EdgeInsets.all(2),        crossAxisCount: 4,        //一行的 Widget 数量        // childAspectRatio: 0.7,        //宽度和高度的比例        children: goods.map((value) {          return Container(            decoration: BoxDecoration(                border: Border.all(                    color: const Color.fromRGBO(233, 233, 233, 0.9), width: 1)),            child: Column(              children: [                Image.network(                  value['skillurl'],                  width: 100,                  height: 200,                ),                const SizedBox(height: 12),                Text(                  value['pordname'],                  textAlign: TextAlign.center,                  style: const TextStyle(fontSize: 20),                )              ],            ),          );        }).toList(),      ),    );  }}

 最后展示的效果:

上一篇:服务器怎么调整参数?

下一篇:云服务器手机怎么下载?