写点什么

《仿盒马》app 开发技术分享 -- 购物车基础功能实现(13)

作者:鸿蒙小林
  • 2025-06-30
    浙江
  • 本文字数:3628 字

    阅读完需:约 12 分钟

技术栈

Appgallery connect

开发准备

上一节我们实现了加入购物车和购物车列表的简单展示。对一个电商类的应用来说,这很显然是不够的,我们的购物车内容应该更加的丰富,他需要用户能自主的去选择想要结算的商品,删除一些不需要的商品,或者取消掉一些本次不结算的商品,同时根据选择的不同,我们需要把相对应的价格和选择的数量等信息传递给用户,帮助用户节省更多的时间。

功能分析

1.商品选中在表中我们定义了多个参数来帮助我们更好的去实现功能,这里我们需要用到这些参数来进行条件判断,当商品选中和未选中时候我们需要修改数据源中 isNeedPay 的状态的,然后渲染列表,以这样的方式去实现。


2.商品加减商品的新增和减少我们也需要针对数据源进行操作,增减我们会控制事先预留的 buyAmount 字段进行加减,同时要对数据做好判断,不要出现减为负数的情况,同时增减都要刷新列表对应条目的状态


3.商品删除商品删除我们使用 ListItem 的 swipeAction 去实现,我们只需要定义好删除的 ui 样式,把相关逻辑写到点击事件中即可


4.价格计算计算选中商品的价格和数量,并且在选中和增减的事件里调用,只要状态变化价格就要有对应的变化。

代码实现

import { CartProductList } from "../entity/CartProductList"import { cloudDatabase } from "@kit.CloudFoundationKit";import { cart_product_list } from "../clouddb/cart_product_list";import { hilog } from "@kit.PerformanceAnalysisKit";import showToast from "../utils/ToastUtils";


let databaseZone = cloudDatabase.zone('default');


@Preview@Componentexport struct CartList {


@State productList:CartProductList[]=[]


@State flag:boolean=false


@State checkCount:number=0@State allPrice:number=0@State allOriginalPrice:number=0


private scroller: ListScroller = new ListScroller();async aboutToAppear(): Promise<void> {


let condition = new cloudDatabase.DatabaseQuery(cart_product_list);let listData = await databaseZone.query(condition);let json = JSON.stringify(listData)this.productList= JSON.parse(json)hilog.info(0x0000, 'testTag', `Succeeded in upserting data, result: ${listData}`);this.getCountPrice()this.flag=true
复制代码


}@Builder itemEnd(item:CartProductList) {Row() {Button('删除').margin(4).onClick(()=>{let index = this.productList.indexOf(item);this.productList.splice(index, 1);})}.padding(10).justifyContent(FlexAlign.SpaceEvenly)}build() {Column(){if (this.flag){List({scroller:this.scroller}){ForEach(this.productList,(item:CartProductList,index:number)=>{ListItem(){Row(){Image(item.isNeedPay?r('app.media.cart_no_check')).height(20).width(20).objectFit(ImageFit.Contain).onClick(()=>{if (item.isNeedPay) {item.isNeedPay=falsethis.productList[index] = new CartProductList(item.id, item.productId, item.productSpecId, item.productName, item.productSpecName,item.buyAmount, item.isNeedPay,item.activityType,item.productImgAddress,item.productOriginalPrice, item.productPrice, item.couponPrice)}else {item.isNeedPay=truethis.productList[index] = new CartProductList(item.id, item.productId, item.productSpecId, item.productName, item.productSpecName,item.buyAmount, item.isNeedPay,item.activityType,item.productImgAddress,item.productOriginalPrice, item.productPrice, item.couponPrice)this.getCountPrice()}


               })             Image(item.productImgAddress)               .height(120)               .width(120)               .margin({left:10})             Column(){               Text(item.productName)                 .fontColor(Color.Black)                 .fontSize(16)
Text(item.productSpecName) .fontColor(Color.Grey) .fontSize(14)
Text(){ Span("¥ ") .fontSize(14) .fontColor(Color.Red) Span(item.productPrice+"") .fontSize(22) .fontColor(Color.Red) }
Text("¥"+item.productOriginalPrice+"") .fontColor('#999') .decoration({ type: TextDecorationType.LineThrough, color: Color.Gray }) .fontSize(16) .margin({left:10}) }
Row(){ Text(" - ") .textAlign(TextAlign.Center) .border({width:0.5,color:Color.Gray}) .fontSize(14) .height(20) .padding({left:7,right:7}) .fontColor(Color.Black) .onClick(()=>{ if (item.buyAmount==1) { showToast("已经是最小数量了") }else { item.buyAmount-- this.productList[index] = new CartProductList(item.id, item.productId, item.productSpecId, item.productName, item.productSpecName, item.buyAmount, item.isNeedPay,item.activityType,item.productImgAddress, item.productOriginalPrice, item.productPrice, item.couponPrice) this.getCountPrice()
} }) .borderRadius({topLeft:5,bottomLeft:5})
Text(item.buyAmount+"") .textAlign(TextAlign.Center) .fontColor(Color.Black) .fontSize(14) .height(20) .padding({left:20,right:20}) .border({width:0.5,color:Color.Gray})

Text(" + ") .textAlign(TextAlign.Center) .fontColor(Color.Black) .fontSize(14) .height(20) .padding({left:7,right:7}) .onClick(()=>{ item.buyAmount++ this.productList[index] = new CartProductList(item.id, item.productId, item.productSpecId, item.productName, item.productSpecName, item.buyAmount, item.isNeedPay,item.activityType,item.productImgAddress, item.productOriginalPrice, item.productPrice, item.couponPrice) this.getCountPrice() }) .border({width:0.5,color:Color.Gray}) .borderRadius({topRight:5,bottomRight:5})
} .justifyContent(FlexAlign.SpaceBetween) } .padding(10) .alignItems(VerticalAlign.Center) } .swipeAction({ end: { builder: () => { this.itemEnd(item) }, actionAreaDistance: 56 } })
})
}
.height('auto') .layoutWeight(1) } Row(){
Text("合计:") .fontColor(Color.Black)
Text(){ Span("¥ ") .fontSize(14) .fontColor(Color.Red) Span(this.allPrice.toFixed(2)) .fontSize(22) .fontColor(Color.Red) }
Blank()

Text("去结算"+"("+this.checkCount+")") .fontColor(Color.White) .padding(10) .borderRadius(20) .backgroundColor('#ccfa1818') } .justifyContent(FlexAlign.SpaceBetween) .padding(10)}
复制代码


}


getCountPrice(){this.allPrice=0this.allOriginalPrice=0this.checkCount=0for (let i = 0; i < this.productList.length; i++) {if (this.productList[i].isNeedPay) {this.checkCount+=this.productList[i].buyAmountthis.allPrice+=this.productList[i].productPricethis.productList[i].buyAmountthis.allOriginalPrice+=this.productList[i].productOriginalPricethis.productList[i].buyAmount}


}
复制代码


}


}


到这里列表的展示价格的计算都已经实现了

用户头像

鸿蒙小林

关注

还未添加个人签名 2025-06-20 加入

还未添加个人简介

评论

发布
暂无评论
《仿盒马》app开发技术分享-- 购物车基础功能实现(13)_鸿蒙小林_InfoQ写作社区