ITPub博客

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

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

原创 HTML5 作者:鸿蒙小林 时间:2025-06-26 13:43:28 0 删除 编辑


## 技术栈


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

@Component

export 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_check'):$r('app.media.cart_no_check'))

                   .height(20)

                   .width(20)

                   .objectFit(ImageFit.Contain)

                   .onClick(()=>{

                     if (item.isNeedPay) {

                       item.isNeedPay=false

                       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)

                     }else {

                       item.isNeedPay=true

                       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()

                     }


                   })

                 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=0

    this.allOriginalPrice=0

    this.checkCount=0

    for (let i = 0; i < this.productList.length; i++) {

      if (this.productList[i].isNeedPay) {

        this.checkCount+=this.productList[i].buyAmount

        this.allPrice+=this.productList[i].productPrice*this.productList[i].buyAmount

        this.allOriginalPrice+=this.productList[i].productOriginalPrice*this.productList[i].buyAmount

      }



    }

  }


}


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


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70046889/viewspace-3089024/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2025-06-26

  • 博文量
    90
  • 访问量
    67514