目录
- 一、服务器端
-
- [1. 资源文件](#1. 资源文件)
- [2. 服务启动](#2. 服务启动)
-
- [2.1. 引入依赖与初始化](#2.1. 引入依赖与初始化)
- [2.2. 中间件配置](#2.2. 中间件配置)
- [2.3. 服务器启动](#2.3. 服务器启动)
- [2.4. 核心数据:模拟服装列表](#2.4. 核心数据:模拟服装列表)
- [2.5. 核心接口:获取服装列表](#2.5. 核心接口:获取服装列表)
-
- [2.5.1 获取分页参数](#2.5.1 获取分页参数)
- [2.5.2 计算分页索引](#2.5.2 计算分页索引)
- [2.5.3 数据切片与循环逻辑](#2.5.3 数据切片与循环逻辑)
- [2.5.4 返回数据](#2.5.4 返回数据)
- 二、客户端
-
- [1. 依赖管理 (Dependencies)](#1. 依赖管理 (Dependencies))
- [2. 项目文件](#2. 项目文件)
-
- [2.1. lib\models](#2.1. lib\models)
-
- [2.1.1. cloth_model.dart](#2.1.1. cloth_model.dart)
- [2.1.2. cloth_model.g.dart](#2.1.2. cloth_model.g.dart)
- [2.2. lib\core\http](#2.2. lib\core\http)
-
- [2.2.1 api_config.dart](#2.2.1 api_config.dart)
- [2.2.2. api_response.dart](#2.2.2. api_response.dart)
- [2.2.3. http_client.dart](#2.2.3. http_client.dart)
- [2.3. lib\api\cloth_api.dart](#2.3. lib\api\cloth_api.dart)
- [2.4. lib\pages\cloth\cloth_list_page.dart](#2.4. lib\pages\cloth\cloth_list_page.dart)
- [2.5. lib\main.dart](#2.5. lib\main.dart)
本文的目的是用来记录前6天实验中涉及的知识和要点及代码解读。
一、服务器端
1. 资源文件
在local_cloth_api文件夹下创建了public文件夹,用来存储图片资源。

2. 服务启动
在local_cloth_api文件夹下创建了server.js文件,用来写服务端启动脚本。这是一个基于 Node.js 和 Express 框架搭建的简单后端服务器,主要功能是提供一个模拟的"服装列表"数据接口,并支持分页。
2.1. 引入依赖与初始化
bash
const cors = require('cors');
const express = require('express');
const app = express();
作用:引入必要的模块。
解读:cors 用于解决浏览器的跨域问题;express 是核心的 Web 框架。
2.2. 中间件配置
bash
app.use(express.static('public'));
app.use(cors());
静态资源服务:public 文件夹里的文件(如图片、HTML、CSS)可以直接通过 URL 访问。例如 public/cloth1.jpg 可以通过 http://localhost:3000/cloth1.jpg 访问。
跨域资源共享:app.use(cors()) 允许任何域名的前端页面访问这个接口,这在开发阶段非常方便。
2.3. 服务器启动
bash
const port = 3000;
app.listen(port, () => {
console.log(`Server running on http://localhost: $ {port}`);
});
解读:服务器启动在 3000 端口,控制台会打印提示信息。
2.4. 核心数据:模拟服装列表
bash
const mockClothData = [ ... ];
解读:这是一个模拟的数据库。数组中包含了 12 个服装对象,每个对象有 id、name(名称)、desc(描述)、image(图片路径)和 score(评分)。
2.5. 核心接口:获取服装列表
定义了一个 GET 接口 /api/localCloth/list。
2.5.1 获取分页参数
bash
const page = parseInt(req.query.page) || 1;
const pageSize = parseInt(req.query.pageSize) || 10;
解读:从 URL 的查询参数中获取当前页码 (page) 和每页数量 (pageSize)。如果前端没传,默认第 1 页,每页 10 条。
2.5.2 计算分页索引
bash
const startIndex = (page - 1) * pageSize;
const endIndex = startIndex + pageSize;
解读:计算出当前页应该从数组的哪个索引开始取数据。
2.5.3 数据切片与循环逻辑
bash
const paginatedClothList = [];
for (let i = startIndex; i < endIndex; i++) {
const loopIndex = i % mockClothData.length;
paginatedClothList.push(mockClothData[loopIndex]);
}
使用了取模运算 (%)。这意味着如果请求的数据超过了 12 条(数据总数),它会从头开始循环。如果你请求第 2 页(page=2, pageSize=10),前 2 条是 11、12,接下来的 8 条会变成 1、2、3...10。这是一种"无限循环"数据的模拟技巧。
2.5.4 返回数据
bash
res.json({
clothList: paginatedClothList
});
解读:将处理好的数据包裹在 clothList 字段中返回给前端。前端拿到的数据格式是 { clothList: [...] }。
二、客户端
1. 依赖管理 (Dependencies)
这个 pubspec.yaml 文件描述了一个具备完整网络请求、JSON 数据处理、图片缓存、列表分页刷新功能的 Flutter 应用。
| 依赖库名称 | 主要用途 |
|---|---|
flutter / cupertino_icons |
Flutter 框架核心及图标支持 |
http / dio |
网络请求库(用于与后端服务器通信) |
cached_network_image |
网络图片加载与缓存 |
pull_to_refresh / easy_refresh |
下拉刷新和上拉加载更多组件 |
flutter_rating_bar |
评分条组件(星星评分) |
json_annotation / json_serializable |
JSON 序列化与反序列化(处理数据模型) |
infinite_scroll_pagination |
分页加载列表(无限滚动) |
Flutter 特定配置 (Flutter)
uses-material-design: true
含义:启用 Google 的 Material Design 图标和样式。如果设为 true,你就可以直接使用 Icons.xxx(如 Icons.add)而无需手动导入图标文件。
2. 项目文件
2.1. lib\models
2.1.1. cloth_model.dart
- 服装相关的模型类代码(cloth_model.dart),核心是通过 json_annotation 实现 JSON 与 Dart 模型的解析,包含单个服装模型 ClothModel 和列表包装模型 ClothListModel。
- ClothModel:单个服装的模型类,包含 id、name、desc、image、score 五个字段,通过 json_annotation 自动生成 JSON 解析代码。
- ClothListModel:服装列表的包装模型,用于解析后端返回的包含 clothList 数组的 JSON 数据,将数组转换为 List。
2.1.2. cloth_model.g.dart
- cloth_model.dart 自动生成的 _cloth_model.g.dart 代码片段,这是运行 build_runner 命令后由 json_serializable 生成的 JSON 解析核心代码。
- 这段自动生成的代码是 ClothModel 与 JSON 互转的具体实现,对应手动定义的 ClothModel.fromJson 和 ClothModel.toJson 方法:
- _$ClothModelFromJson:将 JSON 映射(Map<String, dynamic>)转换为 ClothModel 实例。
- _$ClothModelToJson:将 ClothModel 实例转换为 JSON 映射,用于向后端提交数据。
2.2. lib\core\http
2.2.1 api_config.dart
- 定义了接口基础地址、服装列表接口路径、超时时间和请求头,是网络请求层的核心配置文件。
- 基础地址配置:baseUrl 指向本地 Node 服务的 IP 和端口(192.168.1.2:3000),是所有接口的根地址。
- 接口路径配置:cloth_list_url 拼接出服装列表的完整接口地址(http://192.168.1.2:3000/api/localCloth/list)。
- 网络配置:timeout 定义请求超时时间(10 秒),baseHeaders 定义通用请求头(JSON 格式)。
2.2.2. api_response.dart
- 用于统一封装接口请求的返回结果(状态码、提示信息、数据、是否成功),这是 Flutter 网络层的核心封装类。
- 泛型封装:ApiResponse 使用泛型 ,支持适配不同类型的返回数据(如 ClothListModel、List 等)。
- 核心字段:code(状态码)、msg(提示信息)、data(业务数据)、success(请求是否成功),覆盖接口响应的通用属性。
- 便捷构造方法:
successResponse:快速创建 "请求成功" 的响应实例。
errorResponse:快速创建 "请求失败" 的响应实例。
2.2.3. http_client.dart
- 外部调用 HttpClient.getRequest(url) 发起 GET 请求;
- 内部封装请求头、超时时间,发送请求;
- 请求成功(状态码 200):解析响应体为 List,返回成功响应;
- 请求失败(非 200 / 异常):返回带错误信息的响应;
- 全程通过 ApiResponse 统一返回格式,业务层只需判断 success 字段即可处理结果。
2.3. lib\api\cloth_api.dart
这是一个标准的 Flutter 网络请求脚本,它通过 Dio 发送分页参数,从后端拉取衣服列表数据,并打印日志供开发者调试。
这段代码是一个典型的 Flutter 网络请求层(API 层) 的实现。
简单来说,它的作用是:专门负责与后端服务器"对话",获取衣服(或商品)列表的数据。
📦 核心功能:获取分页数据
这个文件定义了一个名为 ClothApi 的类,其中包含一个静态方法 getClothList。它的主要任务是:
- 接收指令:接收当前页码(page)和每页数量(pageSize)。
- 发起请求:使用 Dio 库向后端接口发送 GET 请求,并附带分页参数。
- 处理结果:打印日志,并将服务器返回的原始数据(response.data)传递给上层业务逻辑(如页面展示)。
2.4. lib\pages\cloth\cloth_list_page.dart
实现了一个 Flutter 页面,主要功能包括:
- 下拉刷新:通过 pull_to_refresh 库实现,刷新时重新加载第 1 页数据。
- 无限上拉加载:通过 infinite_scroll_pagination 库实现,滑动到底部自动加载下一页。
- 列表项展示:包含服装图片(网络加载)、名称、描述、星级评分(原生实现)。
- 异常处理:图片加载失败 / 成功的回调、接口请求失败的提示、加载锁防止重复请求。
2.5. lib\main.dart
项目的入口文件 main.dart,核心是将 ClothListPage 设置为应用首页。
应用入口:main() 函数通过 runApp(const MyApp()) 启动应用,MyApp 是根组件。
路由配置:MaterialApp 将 ClothListPage 设为首页(home: const ClothListPage()),直接打开服装列表页面。
以上是前6天学习一个阶段的总结。
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net