demo 汽车之家(渲染-筛选-排序-模块抽离数据)

效果图展示:

代码截图注释

详情实现笔记

总体目标(按需求点对照代码)

  • 数据模块化、整体渲染框架、筛选/排序的高亮与行为,全部已在 Index.ets + CarData.ets 落地。下面按图片需求 2~4 点逐条总结,并给出关键代码定位与“为什么”。

1. 数据模块化(数据模型/源)

  • CarData.ets 定义强类型模型 Car 与静态数据源 carList,页面只依赖这一个入口。
export interface Car {count: number // 销量image: ResourceStr // 图片series_name: string // 名字rank: number // reduce(热度)id: number // idmin_price: number // 最低价max_price: number // 最高价type: number // 类型 1紧凑汽车 2微型车 3小型车 4中型车
}
  • 页面引入并作为状态初始化,后续所有筛选/排序都基于它更新渲染列表。
import { Car, carList } from '../models/CarData'
@State carList: Car[] = carList//汽车的列表
@State scaleX: number = 1
@State scaleY: number = 1
  • 为什么:强类型防止字段误用;把“原始数据池”与“渲染状态”分离,筛选始终从全量数据重新计算,结果可预期。

2. 渲染汽车列表

  • 2.1 基于提供的数据渲染 List 列表(图片、名称、价格、销量)。
List({ space: 10 }) {ForEach(this.carList, (item: Car, index: number) => {ListItem() {Row({ space: 8 }) {// 名次图标/数字见下节Image(item.image).width(100).syncLoad(true)Column({ space: 10 }) {Text(item.series_name)Text(item.min_price.toFixed(2) + '-' + item.max_price.toFixed(2) + '万').fontColor(Color.Orange).fontSize(15)}
  • 2.2 前三名用奖牌图,之后用序号 index+1
if (index === 0) {Image($r('app.media.ic_homework_first')).width(40)
} else if (index == 1) {Image($r('app.media.ic_homework_second')).width(40)
} else if (index === 2) {Image($r('app.media.ic_homework_third')).width(40)
} else {Text((index + 1).toString()).fontSize(25)
}
  • 为什么:榜单视觉区分前 3;其余用数字简洁直观。

3. 渲染“筛选区/排序区”高亮切换

  • 3.1 筛选区(车型标签文字列表)+ 高亮
filterList = ['全部', '紧凑型车', '微型车', '小型车', '中型车',]
@State filterListActiveIndex: number = 0
ForEach(this.filterList, (item: string, index: number) => {Text(item).fontColor(this.filterListActiveIndex === index ? Color.Red : '#595B5D')
  • 3.2 排序区(文字列表)+ 高亮
sortList = ['热度', '价格', '销量']
@State sortListActiveIndex: number = 0
ForEach(this.sortList, (item: string, index: number) => {Text(item).fontColor(this.sortListActiveIndex === index ? Color.Red : Color.Black)
  • 为什么:用 @State 保存当前索引,通过条件 fontColor 切换高亮,点击只需改索引即可即时反馈。

4. 实现筛选与排序效果

  • 4.1 筛选:点击车型标签 → 过滤对应列表并渲染。
.onClick(() => {this.filterListActiveIndex = index
this.carList = carList.filter((ele: Car, index) => {return item === '全部' ? true : ele.type === this.filterListActiveIndex
})
})
  • 为什么:每次都基于“原始 carList”过滤,避免在上一次结果上叠加筛选造成数据越来越少;利用“索引=type 值”的约定实现最短判断。
  • 4.2 排序:点击排序项 → 对当前数组排序
this.sortListActiveIndex = index
this.carList = this.carList.sort((a: Car, b: Car) => {if (this.sortListActiveIndex === 0) {      // 4.2.1 热度return a.rank - b.rank                    // rank 升序} else if (this.sortListActiveIndex === 1) {// 4.2.2 价格return (a.max_price - a.min_price) - (b.max_price - b.min_price)} else {                                    // 4.2.3 销量return b.count - a.count                  // 降序}
})
  • 为什么:先筛后排符合用户习惯;对“当前结果集”排序即可;sort 原地排序效率高并配合赋值触发 UI 更新。
  • 注意与需求对齐:
    • 需求 4.2.2 写的是“max_price 降序”。当前实现是“价格区间宽度升序”。若要与需求一致,应改为:
      • 价格(最高价降序)比较器:(a, b) => b.max_price - a.max_price

额外:按钮动画

Text('询底价').backgroundColor('#027DFF').padding(5).borderRadius(3).fontColor('#fff').scale({ x: this.scaleX, y: this.scaleY }).onAppear(() => { this.scaleX = 1.1; this.scaleY = 1.1 }).animation({ iterations: -1, playMode: PlayMode.AlternateReverse })
  • 为什么:出现即启动无限往返缩放,形成“呼吸”吸引点击。

小结与对齐校验

  • 整体渲染:顶部标题/图标 + 筛选条 + 时间/排序 + 列表,结构完整;前三名奖牌与序号展示符合 2.2。
  • 高亮:筛选与排序均用 @State 索引控制,点击即时变色。
  • 筛选:点击车型后基于全量数据按 type 过滤,符合 4.1。
  • 排序:热度升序、销量降序已符合 4.2.1/4.2.3;价格需将比较器改为“max_price 降序”以完全符合 4.2.2。

全部代码:

CarData_接口和数据

export interface Car {count: number // 销量image: ResourceStr // 图片series_name: string // 名字rank: number // reduce(热度)id: number // idmin_price: number // 最低价max_price: number // 最高价type: number // 类型 1紧凑汽车 2微型车 3小型车 4中型车
}
export const carList: Car[] = [{count: 30001,image: 'http://p6-dcd.byteimg.com/img/tos-cn-i-dcdx/2b0405ab3ec543bf9bef91533b82899f~tplv-resize:480:0.png',series_name: '凯美瑞',rank: 1,id: 535,min_price: 17.18,max_price: 20.68,type: 4,},{count: 30456,image: 'http://p6-dcd.byteimg.com/img/motor-mis-img/af835d978de92b8342d900c8473c8d88~tplv-resize:480:0.png',series_name: '思域',rank: 2,id: 276,min_price: 9.69,max_price: 15.49,type: 1,},{count: 32178,image: 'http://p9-dcd.byteimg.com/img/tos-cn-i-dcdx/76d8b7dd596a42668c660711eb63ba36~tplv-resize:480:0.png',series_name: '欧拉黑猫',rank: 3,id: 2911,min_price: 5.98,max_price: 10.28,type: 2,},{count: 35690,image: 'http://p3-dcd.byteimg.com/img/tos-cn-i-dcdx/b16feb96960c4b178686faea93e71f3c~tplv-resize:480:0.png',series_name: '秦PLUS DM-i',rank: 4,id: 4802,min_price: 7.98,max_price: 12.58,type: 1,},{count: 37045,image: 'http://p9-dcd.byteimg.com/img/tos-cn-i-dcdx/c582d200e0fe44c7b1b5f3b6134c8849~tplv-resize:480:0.png',series_name: '小蚂蚁',rank: 5,id: 1101,min_price: 5.69,max_price: 8.9,type: 2,},{count: 38967,image: 'http://p1-dcd.byteimg.com/img/tos-cn-i-dcdx/db765ed4695e4d1e808f3344a2637ff8~tplv-resize:480:0.png',series_name: '奥迪A4L',rank: 6,id: 96,min_price: 23.17,max_price: 29.26,type: 4,},{count: 40321,image: 'http://p1-dcd.byteimg.com/img/tos-cn-i-dcdx/a6ee19f8cb8b4ad8bab7f2b3cb0e4fa1~tplv-resize:480:0.png',series_name: 'Polo',rank: 7,id: 391,min_price: 6.39,max_price: 9.79,type: 3,},{count: 42768,image: 'http://p1-dcd.byteimg.com/img/motor-mis-img/5a66c6bc0c1d71c7e6f68f53b902d1b9~tplv-resize:480:0.png',series_name: '奔奔E-Star',rank: 8,id: 4416,min_price: 6.69,max_price: 6.69,type: 2,},{count: 45603,image: 'http://p3-dcd.byteimg.com/img/tos-cn-i-dcdx/b904c6bfc5094657bbcad15af499fd16~tplv-resize:480:0.png',series_name: '飞度',rank: 9,id: 283,min_price: 6.98,max_price: 9.18,type: 3,},{count: 47892,image: 'http://p6-dcd.byteimg.com/img/motor-mis-img/b4f69ed40e9e2f4f40a8874ce323e181~tplv-resize:480:0.png',series_name: '宝马 3 系',rank: 10,id: 145,min_price: 24,max_price: 32.8,type: 4,},{count: 49103,image: 'http://p1-dcd.byteimg.com/img/motor-mis-img/5a47279a2f425d7c1505b60d0478d9a8~tplv-resize:480:0.png',series_name: '威驰',rank: 11,id: 538,min_price: 7.38,max_price: 9.48,type: 3,},{count: 50048,image: 'http://p6-dcd.byteimg.com/img/motor-mis-img/28d677a5f94a5a24103f088dd94c8515~tplv-resize:480:0.png',series_name: '朗逸',rank: 12,id: 393,min_price: 7.2,max_price: 11.39,type: 1,},{count: 50569,image: 'http://p3-dcd.byteimg.com/img/motor-mis-img/44c013067df2032cc03b6031eb68bf05~tplv-resize:480:0.png',series_name: '速腾',rank: 13,id: 414,min_price: 9.19,max_price: 13.69,type: 1,},{count: 51377,image: 'http://p9-dcd.byteimg.com/img/motor-mis-img/89991e9322440768e5f67b551d6e7ee5~tplv-resize:480:0.png',series_name: '迈腾',rank: 14,id: 415,min_price: 14.79,max_price: 21.49,type: 4,},{count: 52486,image: 'http://p1-dcd.byteimg.com/img/motor-mis-img/71bb241f24d3e20b2ee3adca8b6559fe~tplv-resize:480:0.png',series_name: '比亚迪e1',rank: 15,id: 3174,min_price: 5.99,max_price: 7.99,type: 2,},{count: 53098,image: 'http://p9-dcd.byteimg.com/img/tos-cn-i-dcdx/f5483079e6094fb898c14f3b3d6c1493~tplv-resize:480:0.png',series_name: '轩逸',rank: 16,id: 1145,min_price: 6.98,max_price: 14.19,type: 1,},{count: 54326,image: 'http://p6-dcd.byteimg.com/img/motor-mis-img/0d4b71e7270960f73f1e9370febad7cc~tplv-resize:480:0.png',series_name: 'YARiS L 致炫',rank: 17,id: 533,min_price: 6.88,max_price: 10.88,type: 3,},{count: 55067,image: 'http://p3-dcd.byteimg.com/img/tos-cn-i-dcdx/287e133f10e1402386d901c399885fbf~tplv-resize:480:0.png',series_name: '五菱宏光MINIEV',rank: 18,id: 4499,min_price: 2.98,max_price: 9.99,type: 2,},{count: 56234,image: 'http://p1-dcd.byteimg.com/img/motor-mis-img/69904c721ef8a45afecf7d777a1806ef~tplv-resize:480:0.png',series_name: 'MINI',rank: 19,id: 38,min_price: 18.98,max_price: 34.33,type: 3,},{count: 58973,image: 'http://p9-dcd.byteimg.com/img/tos-cn-i-dcdx/01ea2955a1cb44ff8f048e3deabf2c17~tplv-resize:480:0.png',series_name: '雅阁',rank: 20,id: 289,min_price: 12.58,max_price: 17.48,type: 4,},
]

界面结构和逻辑代码

import { Car, carList } from '../models/CarData'
@Entry
@Component
struct Page11_carHome {// 筛选条件filterList = ['全部', '紧凑型车', '微型车', '小型车', '中型车',]//筛选车型的默认高亮下标@State filterListActiveIndex: number = 0// 排序条件sortList = ['热度', '价格', '销量']//每种车型的(热度, 价格, 销量)筛选默认的高亮@State sortListActiveIndex: number = 0//汽车列表筛@State carList: Car[] = carList//汽车的列表@State scaleX: number = 1@State scaleY: number = 1// 获取当前时间(年月日)getTime() {const date: Date = new Date()const year = date.getFullYear()const month = date.getMonth() + 1const day = date.getDate()return `${year}年${month}月${day}日`}build() {Column() {// 顶部区域Stack() {Text('汽车之家排行榜').fontSize(18)Row({ space: 5 }) {Image($r('app.media.ic_public_arrow_left')).width(25)Blank()Image($r('app.media.ic_public_share')).width(25)Image($r('app.media.ic_public_question')).width(25)}.width('100%').padding(10)}Scroll() {Row({ space: 10 }) {// 筛选条件['全部', '紧凑型车', '微型车', '小型车', '中型车',]ForEach(this.filterList, (item: string, index: number) => {Text(item).fontColor(this.filterListActiveIndex === index ? Color.Red : '#595B5D').backgroundColor('#ccc').borderRadius(5).padding({top: 5,bottom: 5,left: 8,right: 8}).fontSize(14).onClick(() => {this.filterListActiveIndex = index// 注释的有误//   //  车的类型//   if (item === '全部') {//     this.carList = carList.filter((ele: Car, index: number) => {//       return true//     })//   }//   else {//     this.carList = carList.filter((ele: Car, index: number) => {//       if (item === '紧凑车型') {//         return  ele.type===1//       } else if (item === '微型车') {//         return  ele.type===2//       } else if (item === '小型车') {//         return  ele.type===3//       } else {//         return  ele.type===4//       }//     })//   }// //   筛选//   this.carListthis.carList = carList.filter((ele: Car, index) => {return item === '全部' ? true : ele.type === this.filterListActiveIndex})})})}.height(50).margin({left: 5,right: 5,bottom: 8}).border({ width: { bottom: 1 }, color: '#ccc' })}.height(50).scrollable(ScrollDirection.Horizontal).scrollBar(BarState.Off)// 排序条件(自己实现)Row() {Text(this.getTime())//时间(年月日显示).fontColor('#6D7177')Row({ space: 8 }) {// ['热度', '价格', '销量']ForEach(this.sortList, (item: string, index: number) => {Text(item).fontColor(this.sortListActiveIndex === index ? Color.Red : Color.Black).onClick(() => {this.sortListActiveIndex = index//列表的筛选this.carList =this.carList.sort((a: Car, b: Car) => {if (this.sortListActiveIndex === 0) {// 热度升序return a.rank - b.rank} else if (this.sortListActiveIndex === 1) {// 价格降序return (a.max_price - a.min_price) - (b.max_price - b.min_price)} else {//   销量降序return b.count - a.count}})})})}}.width('100%').justifyContent(FlexAlign.SpaceBetween).padding({top: 15,left: 10,right: 10,bottom: 15})// 列表区域(自己实现)List({ space: 10 }) {ForEach(this.carList, (item: Car, index: number) => {ListItem() {Row({ space: 8 }) {if (index === 0) {Image($r('app.media.ic_homework_first')).width(40)} else if (index == 1) {Image($r('app.media.ic_homework_second')).width(40)} else if (index === 2) {Image($r('app.media.ic_homework_third')).width(40)} else {Text((index + 1).toString()).fontSize(25)}Image(item.image).width(100).syncLoad(true)Column({ space: 10 }) {Text(item.series_name)Text(item.min_price.toFixed(2) + '-' + item.max_price.toFixed(2) + '万').fontColor(Color.Orange).fontSize(15)}.height('100%').layoutWeight(1).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Start)Column({ space: 6 }) {Text(item.count.toString()).fontWeight(700)Text('全国销量').fontColor('#67696C').fontSize(13)Text('询底价').backgroundColor('#027DFF').padding(5).borderRadius(3).fontColor('#fff').scale({ x: this.scaleX, y: this.scaleY }).onAppear(() => {this.scaleX = 1.1this.scaleY = 1.1}).animation({iterations: -1,playMode: PlayMode.AlternateReverse})}}}.width('100%').height(110)})}.width('100%').padding({ left: 10, right: 10 }).divider({strokeWidth: 1,color: '#ccc'}).scrollBar(BarState.Off)}.width('100%').height('100%')}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919734.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

双重机器学习DML介绍

本文参考: [1]文心一言回答; 一、核心原理与数学框架 双重机器学习(Double Machine Learning, DML)由Chernozhukov等学者于2018年提出,是一种结合机器学习与传统计量经济学的因果推断框架。其核心目标是在高维数据和非…

【图像算法 - 21】慧眼识虫:基于深度学习与OpenCV的农田害虫智能识别系统

摘要: 在现代农业生产中,病虫害是影响作物产量和品质的关键因素之一。传统的害虫识别依赖人工巡查,效率低、成本高且易出错。本文将介绍如何利用深度学习与OpenCV构建一套高效的农田害虫智能识别系统。该系统能够自动识别10类常见农业害虫&a…

循环神经网络实战:GRU 对比 LSTM 的中文情感分析(三)

循环神经网络实战:GRU 对比 LSTM 的中文情感分析(三) 文章目录循环神经网络实战:GRU 对比 LSTM 的中文情感分析(三)前言数据准备(与 LSTM 相同)模型搭建(GRU)…

学习游戏制作记录(制作提示框以及使用键盘切换UI)8.21

1.制作装备提示框创建提示框,添加文本子对象,用来描述名称,类型以及属性加成挂载垂直分配组件和文本大小适配组件,这样图像会根据文本大小来调整自己创建UI_ItemTip脚本并挂载在文本框上:[SerializeField] private Tex…

chapter07_初始化和销毁方法

一、简介 一个Bean,在进行实例化之后,需要进行两种初始化 初始化属性,由PropertyValues进行赋值初始化方法,由ApplicationContext统一调用,例如加载配置文件 Bean的初始化与销毁,共有三种方式(注…

open webui源码分析6-Function

一、Functions简介 可以把Tools作为依赖于外部服务的插件,Functions就是内部插件,二者都是用来增强open webui的能力的。Functions是轻量的,高度可定制的,并且是用纯Python编写的,所以你可以自由地创建任何东西——从新…

C2039 “unref“:不是“osgEarth::Symbology::Style”的成员 问题分析及解决方法

在osgEarth2.10中实现多线段连续测量功能时,遇到下图中的错误; 经过测试和验证,主要问题出现在下图圈出代码的定义上 图22-1 对于22-1中的两个变量这样定义是错误的。因为Style类没有继承自osg::Referenced,因此不能与osg::ref_ptr配合使用

GitHub 热榜项目 - 日榜(2025-08-19)

GitHub 热榜项目 - 日榜(2025-08-19) 生成于:2025-08-19 统计摘要 共发现热门项目:12 个 榜单类型:日榜 本期热点趋势总结 本期GitHub热榜呈现三大技术热点:1)AI原生开发持续爆发,Archon OS、Parlant等…

ingress 配置ssl证书

模拟环境举例&#xff1a; # 生成带 OU 的证书配置文件 cat > csr.conf <<EOF [ req ] default_bits 2048 prompt no default_md sha256 distinguished_name dn[ dn ] C CN ST Beijing L Beijing O YourCompany, Inc. # 组织名称 (必填) OU DevOps De…

Pandas 合并数据集:concat 和 append

文章目录Pandas 合并数据集&#xff1a;concat 和 append回顾&#xff1a;NumPy 数组的拼接使用 pd.concat 进行简单拼接重复索引将重复索引视为错误忽略索引添加多级索引&#xff08;MultiIndex&#xff09;键使用连接&#xff08;Join&#xff09;方式拼接append 方法Pandas …

2025年5月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(七)

本文主要回顾2025年上半年(2025-5-24)系统架构设计师考试上午综合知识科目的选择题,同时附带参考答案、解析和所涉知识点。 2025年5月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(一) 2025年5月架构设计师综合知识真题回顾,附参考答案、解析及所涉知识点(…

面向RF设计人员的微带贴片天线计算器

微带贴片天线和阵列可能是仅次于单极天线和偶极天线的最简单的天线设计。这些天线也很容易集成到PCB中&#xff0c;因此通常用于5G天线阵列和雷达等高级系统。这些天线阵列在基谐模式和高阶模式下也遵循一组简单的设计方程&#xff0c;因此您甚至可以在不使用仿真工具的情况下设…

明基RD280U编程显示器深度测评:码农的「第二块键盘」竟然会发光?

文章目录前言一、开箱篇&#xff1a;当理工男遇到「俄罗斯套娃式包装」二、外观篇&#xff1a;深空灰的「代码容器」1. 桌面变形记2. 保护肩颈的人体工学设计三、显示篇&#xff1a;给代码做「光子嫩肤」1. 28寸超大大屏 3:2屏比 4K超清2.专业编程模式&#xff0c;让代码一目…

算法114. 二叉树展开为链表

题目&#xff1a;给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。 展开后的单链表应该与二叉树 先序遍历 顺序相同。…

智慧能源管理系统:点亮山东零碳园区的绿色引擎

一、概述在全球积极践行“双碳”目标的时代浪潮下&#xff0c;山东作为经济大省&#xff0c;正全力推动产业的绿色变革&#xff0c;零碳园区建设成为其中的关键一环。《山东省零碳园区建设方案》明确规划&#xff0c;到2027年建成15个左右省级零碳园区 &#xff0c;到2030年进一…

分布式日志分析平台(ELFK 与 EFK)理论

一、日志分析平台核心概念在分布式系统中&#xff0c;日志是系统运行状态监控、问题排查和业务分析的重要依据。随着系统规模扩大&#xff0c;单机日志管理方式已无法满足需求&#xff0c;分布式日志分析平台应运而生。其核心目标是实现日志的集中收集、统一处理、高效存储和可…

CoreShop微信小程序商城框架开启多租户-添加一个WPF客户端以便进行本地操作--读取店铺信息(6)

本节内容&#xff0c;使用登录的token进行店铺信息读取&#xff0c;顺利的话&#xff0c;进行EXCEL上传测试。 1。在后台编写 读取店铺信息代码 1.1 查看原来铺店信息在什么位置&#xff0c;店铺的表格为CoreCmsStore#region 获取列表// POST: Api/CoreCmsStore/GetPageList///…

UE5关卡蓝图能不能保存副本呀?

提问 关卡蓝图能不能保存副本呀&#xff1f; 回答 在 UE 里&#xff0c;“关卡蓝图&#xff08;Level Blueprint&#xff09;”本身其实是不能直接复制/保存成独立资源的&#xff0c;因为它和具体的 **Level&#xff08;.umap 文件&#xff09;**是绑定的——相当于一个“场景脚…

机器学习数据预处理学习报告

一、学习背景与目的在机器学习流程中&#xff0c;数据预处理是保障模型训练效果的关键环节。原始数据常存在缺失值、量纲不一致、特征格式不匹配等问题&#xff0c;直接影响模型对数据规律的学习。本次学习围绕 Pandas 与 Scikit-learn&#xff08;sklearn&#xff09;工具库&a…

git旧仓库迁移到新仓库

git旧仓库迁移到新仓库 A仓库(旧仓库)&#xff1a;git172.16.21.21:xxxx_software/Ni-Handler-Mgr.git B仓库(新仓库)&#xff1a;git172.16.11.11:yyyy/hostpc/ni-handler-mgr.git Step1 新建新仓库 创建新 GitHub 仓库‌ 在 GitHub 页面点击 “New repository”&#xff0c;命…