赞
踩
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,
- }
-
- // 创建请求类:封装dio
- class 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<T> request<T>(
- String path, {
- DioMethod method = DioMethod.get,
- Map<String, dynamic>? 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网络请求,并在里面创建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<Lists> createState() => _ListsState();
- }
-
- class _ListsState extends State<Lists> {
- // 列表数据
- 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<Widget> _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: <Widget>[
- 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: <Widget>[
- Image.network(
- value['skillurl'],
- width: 100,
- height: 200,
- ),
- const SizedBox(height: 12),
- Text(
- value['pordname'],
- textAlign: TextAlign.center,
- style: const TextStyle(fontSize: 20),
- )
- ],
- ),
- );
- }).toList(),
- ),
- );
- }
- }
最后展示的效果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。