当前位置: 首页 > news >正文

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.dtcms.com/a/342858.html

相关文章:

  • Linux之Ansible自动化运维(二)
  • Linux内核源码详解--缺页异常(Page Fault)处理的核心函数handle_pte_fault
  • Maven(三)
  • Class A 包含字段 x Class B 也包含字段 x,如果判断List<A> lista 和 List<B> listb 有相同的 x?
  • 基于websocket聊天室的基本点
  • SQL中的游标
  • html ajax前端页面
  • 51单片机-驱动直流电机模块教程
  • 单片机\物联网\51单片机\嵌入式开发\软硬件结合的基于STM32的电梯管理系统的设计/基于STM32的电梯运行系统的设计
  • 【华为OD-C卷-020 -关联端口组合并 100分(python、java、c++、js、c)】
  • 解决 uniapp 修改index.html文件不生效的问题
  • PCB文件怎么快速判断是通孔还是盲孔呢?
  • Git 2.15.0 64位安装步骤Windows详细教程从下载到验证(附安装包下载)
  • 14、外部中断
  • 【科普向-第三篇】汽车电子MCU操作系统详解:CP AUTOSAR与FreeRTOS
  • 1688电商商品大数据采集之路 技术篇
  • 嵌入式接口通识知识之PWM接口
  • 机器学习聚类与集成算法全解析:从 K-Means 到随机森林的实战指南
  • 从系统漏洞归零到候诊缩短20%:一个信创样本的效能革命
  • 播放器视频后处理实践(一)
  • 视频加水印 视频加水印软件 视频加动态水印
  • 音视频面试题集锦第 29 期
  • 如何有效防止视频在浏览器播放时被录屏?
  • 全媒体人才培育对接会:国际数字影像产业园赋能企业发展
  • 如何学习编程
  • 完全背包(模板)
  • Mysql基础(③事务)
  • [ Servlet 服务器]
  • LTM框架Letta
  • Java项目:基于SpringBoot和VUE的在线拍卖系统(源码+数据库+文档)