鸿蒙HarmonyOS Next练手学习项目购物车功能,联动全选反选、数量总计

ops/2025/3/28 7:38:51/

在这里插入图片描述
点击商品,进行勾选商品。商品列表全部点击,全选状态为已选择,点击取消某个商品,全选状态反选。删除某个商品还没有开发,练手的小功能,记录一下

import ShopCarEntity from './ShopCarEntity'@Entry
@Component
export default struct ShopCarPage {@State carList: ShopCarEntity[] = []@State totalPrice: number = 0@State totalCount: number = 0@State isSelectAll: boolean = false//已选择的数量@State selectNum: number = 0@State isSelectOneOrAll: boolean = falseaboutToAppear(): void {let shopCar = new ShopCarEntity()shopCar.id = 1shopCar.goods_id = 1shopCar.user_id = 1shopCar.order_id = 1shopCar.goods_desc = '电脑'shopCar.goods_default_price = 1shopCar.goods_default_icon ='https://img10.360buyimg.com/n7/jfs/t3499/165/739574790/179345/251c51d4/58126465Na27a9bf0.jpg'this.carList.push(shopCar)let shopCar1 = new ShopCarEntity()shopCar1.id = 2shopCar1.goods_id = 2shopCar1.user_id = 2shopCar1.order_id = 2shopCar1.goods_desc = '手机'shopCar1.goods_default_price = 1shopCar1.goods_default_icon ='https://img10.360buyimg.com/n7/jfs/t3499/165/739574790/179345/251c51d4/58126465Na27a9bf0.jpg'this.carList.push(shopCar1)let shopCar2 = new ShopCarEntity()shopCar2.id = 3shopCar2.goods_id = 3shopCar2.user_id = 3shopCar2.order_id = 3shopCar2.goods_desc = '智慧屏'shopCar2.goods_default_price = 1shopCar2.goods_default_icon ='https://img10.360buyimg.com/n7/jfs/t3499/165/739574790/179345/251c51d4/58126465Na27a9bf0.jpg'this.carList.push(shopCar2)}/*** 计算总价和数量*/countTotalNumber() {let tempTotalPrice = 0let tempTotalCount = 0this.carList.forEach((item: ShopCarEntity) => {if (item.isSelected) {tempTotalPrice += item.goods_default_price * item.counttempTotalCount += item.count}})this.totalPrice = tempTotalPricethis.totalCount = tempTotalCount}/*** 处理商品单选操作* @param state*/carItemSelectChanged(status: boolean, index: number) {let newCarList: ShopCarEntity[] = []//如果选择的数量等于集合数量this.isSelectOneOrAll = falsethis.carList.forEach((item: ShopCarEntity, itemIndex: number) => {if (itemIndex === index) {if (status === true) {this.selectNum++} else {if (this.selectNum === 0) {this.selectNum = 0} else {this.selectNum--}}//已选数量===集合数量 就是全选状态if (this.selectNum === this.carList.length) {this.isSelectAll = truethis.selectNum = 0} else {this.isSelectAll = false}item.isSelected = statusitem.itemKey = `${Math.random()}*${item.id}-${Math.random()}`}newCarList.push(item)})this.carList = newCarList//计算总价和数量this.countTotalNumber()}/*** 增加商品数量* @param index*/addGoodsCount(index: number) {let newCarList: ShopCarEntity[] = []this.carList.forEach((item: ShopCarEntity, itemIndex: number) => {if (itemIndex === index) {item.count++item.itemKey = `${Math.random()}*${item.id}-${Math.random()}`}newCarList.push(item)})this.carList = newCarList//只有选中商品时才计算总价和数量if (this.carList[index].isSelected) {this.countTotalNumber()}}/*** 减少商品数量* @param index*/reduceGoodsCount(index: number) {let newCarList: ShopCarEntity[] = []this.carList.forEach((item: ShopCarEntity, itemIndex: number) => {if (itemIndex === index) {item.count--item.itemKey = `${Math.random()}*${item.id}-${Math.random()}`}newCarList.push(item)})this.carList = newCarList//只有选中商品时才计算总价和数量if (this.carList[index].isSelected) {this.countTotalNumber()}}/*** 全选和反选*/selectAllCarList(selectState: boolean) {let newCarList: ShopCarEntity[] = []if(selectState){//代表点击了全选this.isSelectOneOrAll = true}//如果是ture 赋值if (selectState) {this.selectNum = this.carList.length} else {//点击取消全选 那就是选择数量是0if(this.selectNum===this.carList.length){//如果是单独点击列表不能设置0this.selectNum = 0}}if (this.selectNum === this.carList.length || this.isSelectOneOrAll) {this.carList.forEach((item: ShopCarEntity) => {if (this.selectNum === 0 !&& selectState) {}else{item.isSelected = selectStateitem.itemKey = `${Math.random()}*${item.id}-${Math.random()}`newCarList.push(item)}})this.carList = newCarList}//计算总价和总数量this.countTotalNumber()}/*** 给ItemView生成唯一的Key*/generatorItemViewKey(data: ShopCarEntity): string {if (data.itemKey) {return data.itemKey}return `${data.goods_id}`}build() {Flex({ direction: FlexDirection.Column }) {//标题部分this.TitleBarComponent()//商品列表this.CarListComponent()//底部操作,只有列表有数据时才展示出来if (this.carList.length > 0) {this.BottomOptionsComponent()}}.width('100%').height('100%')}/*** 标题部分*/@BuilderTitleBarComponent() {Stack({ alignContent: Alignment.End }) {Text('购物车').width('100%').textAlign(TextAlign.Center).fontColor(Color.Black).fontSize(16).fontWeight(FontWeight.Bold)}.width('100%').height('56vp')}/*** 商品列表*/@BuilderCarListComponent() {Scroll() {Column() {if (this.carList.length > 0) {List({ space: 2 }) {ForEach(this.carList, (item: ShopCarEntity, index: number) => {ListItem() {this.CarItemComponent(item, index)}}, (item: ShopCarEntity) => this.generatorItemViewKey(item))}} else {this.EmptyComponent()}}.width('100%').height('100%')}.width('100%').flexGrow(1)}/*** 商品ItemView组件* @param data*/@BuilderCarItemComponent(data: ShopCarEntity, index: number) {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {//复选框Checkbox().width(20).height(20).select(data.isSelected).selectedColor($r('app.color.focus_color')).onChange((value: boolean) => {this.carItemSelectChanged(value, index)})//商品主图Image(data.goods_default_icon).width(100).margin({ left: 10, right: 10 }).objectFit(ImageFit.Contain).syncLoad(true)//解决图片刷新闪烁问题.key(data.id.toString())//商品描述和价格Column() {//商品描述Text(data.goods_desc).fontSize(12).fontColor(Color.Black).maxLines(2).textOverflow({ overflow: TextOverflow.Ellipsis })//价格Text() {Span('价格:').fontSize(12).fontColor(Color.Black)Span(`${data.goods_default_price} 元`).fontColor($r('app.color.focus_color')).fontSize(12)}.margin({ top: 5, bottom: 5 })//数量加减Row() {Text('数量:').fontSize(12).fontColor(Color.Black)Counter() {Text(`${data.count}`).fontSize(12).key(data.count.toString())}.width(100).height(20).onInc(() => {if (data.count < 50) {this.addGoodsCount(index)}}).onDec(() => {if (data.count > 1) {this.reduceGoodsCount(index)}})//空白组件Blank().layoutWeight(1)//只有当前商品选中时才显示if (data.isSelected) {Image($r('app.media.ic_delete')).width(15).objectFit(ImageFit.Contain).onClick(() => {})}}.alignItems(VerticalAlign.Center)}.margin({ right: 5 }).alignItems(HorizontalAlign.Start)}.padding({ left: 5, right: 5 }).backgroundColor(Color.White)}@BuilderEmptyComponent() {Column() {Column() {Image($r('app.media.ic_empty')).width(70).objectFit(ImageFit.Contain)Text('您还没有添加购物车').fontColor(Color.Grey).fontSize(14).margin({ top: 5 })}.justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}.width('100%').height('100%').justifyContent(FlexAlign.Center)}/*** 底部操作*/@BuilderBottomOptionsComponent() {Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {//全选和总价Row() {Checkbox().width(15).height(15).select(this.isSelectAll).selectedColor($r('app.color.focus_color')).onChange((value: boolean) => {this.isSelectAll = valuethis.selectAllCarList(value)})Text('全选').fontColor(Color.Black).fontSize(12)//总价Text() {Span('总价:').fontColor(Color.Black).fontSize(12).fontWeight(FontWeight.Bold)Span(`${this.totalPrice}`).fontColor($r('app.color.focus_color')).fontSize(12)Span(' 元').fontColor(Color.Black).fontSize(12).fontWeight(FontWeight.Bold)Span(`(${this.totalCount}件)`).fontColor(Color.Black).fontSize(12).fontWeight(FontWeight.Bold)}.textAlign(TextAlign.Start).margin({ left: 20 })}.margin({ left: 10 }).height('100%')//立即结算Button('立即结算').width(80).height(35).fontSize(12).margin({ right: 10 }).backgroundColor($r('app.color.focus_color')).onClick(() => {})}.width('100%').height('50vp').backgroundColor(Color.White)}
}

http://www.ppmy.cn/ops/167574.html

相关文章

KMP-子串匹配算法-关键点理解

1.理解next[]数组的使用与来历 2.求解next[]数组 一、kmp算法的原理 首先观察暴力解法&#xff1a;假设主串为&#xff1a;abdxxabc&#xff0c;模式串为abxxabd。 暴力解法&#xff0c;就是对主串每个字符作为第一个字符&#xff0c;开始和模式串比较。 比如&#xff1a;从…

人工智能之数学基础:线性方程组求解的得力助手——增广矩阵

本文重点 增广矩阵是一个极具实用价值的工具,尤其在处理线性方程组时,它展现了卓越的功效。通过整合系数和常数项,增广矩阵简化了计算过程并提供了判断方程组解集的有效方法。 增广矩阵的起源与定义 增广矩阵的概念源于线性方程组求解的需求。在解决线性方程组时,我们常…

oracle 索引

Oracle 数据库中的索引是优化查询性能的重要工具&#xff0c;其类型多样&#xff0c;适用于不同场景。以下是 Oracle 索引的主要分类及特点&#xff1a; 1.B-Tree 索引&#xff08;平衡树索引&#xff09; 特点&#xff1a; 默认索引类型&#xff0c;树形结构&#xff08;根、…

前端技巧:精准判断登录设备是移动端还是 PC 端

前端技巧&#xff1a;精准判断登录设备是移动端还是PC端 在前端开发过程中&#xff0c;判断用户的登录设备究竟是移动端还是PC端&#xff0c;这一需求极为常见。比如&#xff0c;为了给用户提供更适配的页面布局和交互体验&#xff0c;我们就需要知晓设备类型。下面就为大家详…

aws训练快速入门教程

AWS 相关核心概念 简洁地介绍一下AWS训练云服务的核心关联概念: AWS核心服务层: 基础设施层: EC2(计算), S3(存储), RDS(数据库)等人工智能层: SageMaker(训练平台), AI服务等 机器学习服务分级: 高层: 预构建AI服务(开箱即用)中层: SageMaker(主要训练平台)底层: 框架和基…

Postman高级功能深度解析:Mock Server与自动化监控——构建高效API测试与监控体系

引言&#xff1a;Postman在API开发中的核心价值 在数字化时代&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为系统间交互的“神经网络”&#xff0c;其质量直接影响用户体验与业务连续性。然而&#xff0c;传统API测试面临两大挑战&#xff1a; 开发阶段依赖…

java TCP UDP 客户端访问例子和对比差异

Java TCP客户端示例 import java.io.*; import java.net.*;public class TCPClient {public static void main(String[] args) {try (Socket socket new Socket("localhost", 12345); // 连接服务端PrintWriter out new PrintWriter(socket.getOutputStream(), t…

T-CSVT投稿记录

文章目录 期刊介绍1. 期刊概况2. 期刊定位与分类3. 研究主题4. 主编与编委5. 投稿与发表6. 期刊影响力与代表性成果7. 总结 真实投稿时间节点 期刊介绍 IEEE Transactions on Circuits and Systems for Video Technology (TCSVT) 是国际电子电气工程师学会&#xff08;IEEE&am…