鸿蒙应用开发之仿黑马智慧商城购物车页

需要之前已经登录账户并成功添加商品至购物车。

没有的可以去黑马官方那登录并添加商品至购物车。


前言

简化了黑马全选与单选商品的逻辑(其实就是我不会-_-)

  需要用到黑马智慧商城接口。地址:wiki - 智慧商城-实战项目 (apifox.com)


一、分析布局

如图:总体布局为纵向布局。 

1.顶部

之前我们封装过一个组件,上期有讲,现在我们复用一次就好了。

 

代码:

//头部
      Row(){
        topContent({title:'购物车'})
      }.width('100%').padding('2%').layoutWeight(1)//设置row在整个column中的高度比

2.菜单

在一个row中左右对齐(需要设置row的宽度)。

代码:

 //菜单
      Row(){
        Text(){
          Span('共')
          Span(this.cartData.length.toString()).fontSize(25).fontColor(Color.Red)
          Span('种商品')
        }.fontSize(25)
        Text(this.isDelete ? '编辑' : '返回')
          .fontSize(25).fontWeight(800)
          .onClick(()=>{
            
          })
      }.width('100%').padding('2%').justifyContent(FlexAlign.SpaceBetween).layoutWeight(1)

 3.商品列表

将商品列表封装成一个子组件(必须是一个组件),通过foreach循环渲染。

注意:商品列表可能有许多个,会超出屏幕的高度,所以我们使用list组件。给list组件设定一个高度,那样就可以实现滑动并不会超出屏幕范围啦。

如图2效果,向左滑动即可展示删除按钮。

代码:

//商品列表
        List({space:5}){
          ForEach(this.cartData,(item:cartInfo,index:number)=>{
            ListItem(){
              //封装的商品子组件
              cartItem()
            }.swipeAction({end:this.deleteCartShop(item.id)})//向左滑动展示的内容
          })
        }.width('100%').layoutWeight(9).padding('2%')

cartItem组件代码:

//子组件cartItem的UI代码
    Row({space:5}){
      //正常情况,不显示单选框,默认一个空白占位
      if(this.show){
        Text()
          .width('5%')
      }else {
        //删除情况:则展示单选框
        Radio({ value: 'Radio1', group: 'radioGroup' })
          .width('5%')
          .checked(this.arr.flag)
          .onChange((value: boolean) => {
              
          })
      }
      //商品图片
      Image(this.arr.url)
        .width('30%').objectFit(ImageFit.Fill)
      Column({space:10}){
        //商品名称
        Text(this.arr.name).fontSize(20).fontWeight(700)
          .width('85%').maxLines(3).textOverflow({overflow:TextOverflow.Ellipsis})

        Row({space:10}){
          //商品的总价
          Text((this.arr.price*this.arr.number).toString())
            .width('30%')
            .fontSize(22).fontColor(Color.Red)
          //占位符
          Blank()
          Text('-')
            .width('15%').border({width:1,color:Color.Orange}).textAlign(TextAlign.Center)
            .fontSize(30).fontColor(Color.Black).fontWeight(800)
            .onClick(()=>{
              
            })
          Text(this.arr.number.toString())
            .fontSize(25).fontWeight(FontWeight.Bold)
          Text('+')
            .width('15%').border({width:1,color:Color.Orange}).textAlign(TextAlign.Center)
            .fontSize(30).fontColor(Color.Black).fontWeight(800)
            .onClick(()=>{
             
            })
        }
      }.width('65%').height('100%').alignItems(HorizontalAlign.Start).justifyContent(FlexAlign.SpaceEvenly)
    }.width('100%').height(180).border({width:2,color:"#ff480047"}).borderRadius(20)
  }

 4.底部

底部内容固定在屏幕的底下,展示用户所有的商品总价(省去了全选框)和购买按钮。

另外,当我们点击菜单栏中的编辑时,底部展示的是删除商品的按钮,如上图3。

代码:

//根据状态判断展示哪个内容
    if(this.isDelete){
        //底部
        Row(){
          Text('合计:').fontSize(20).margin({left:10})
            //获取商品总价
          Text(this.cartData.reduce((acc,obj)=>acc+obj.number*obj.price,0).toString())
            .width('40%').fontSize(20).fontColor(Color.Red)
          Button('结算')
            .width('35%').backgroundColor(Color.Red).margin({left:10})
            .onClick(()=>{

            })
        }.width('100%').padding('2%').layoutWeight(1)
      }else {
        //底部
        Row(){
          Button('删除商品')
            .width('98%').backgroundColor(Color.Red).margin({left:10})
            .onClick(()=>{
              
            })
        }.width('100%').padding('2%').layoutWeight(1).justifyContent(FlexAlign.Center)
      }

二、获取数据

1.获取首选项的Token

上期我们详讲了,如何获取Token并存储,这里不展示了。

代码:

    const a = await preferences.getPreferences(this.context,"tokensss")
    const b = await a.get("tokensss","")
    this.token = b.toString()//将首选项中的Token值赋给变量

2.获取购物车数据

该接口为get请求,需要的参数为Token。

代码:

//获取购物车列表数据
  async getCartData(){
    const data = await axios.get('https://smart-shop.itheima.net/index.php?s=/api/cart/list',{
      //头部参数
      headers:{
        ['Access-Token']:this.token,
        platform:'H5'
      }})
    //定义数据的长度
    const len = data.data.data.list.length
    //简化
    const con = data.data.data.list
    //循环并赋值,将数据存储到数组中,cartInfo为一个类。
    for (let i = 0; i < len; i++) {
      var item = new cartInfo(false,con[i].goods_id,con[i].goods.goods_images[0].preview_url,con[i].goods.goods_name,con[i].goods.goods_price_min,con[i].goods_num,con[i].goods.stock_total)
      this.cartData.push(item)
    }
  }

3.自定义一个类

 注意:这里的this.cartData是一个自定义的数组,因为涉及到数组里面包函对象的格式,当我们更改数组中某个对象的属性时,是框架检测不到的,即不能同步刷新UI界面,所以我们必须要用@Observed和@ObjectLink来实现对数据的更改时能同步刷新UI。

关于@Observed和@ObjectLink的知识,详情请参考官网: 

@Observed装饰器和 @ObjectLink装饰器:嵌套类对象属性变化 (openharmony.cn)

 cartInfo类的代码:

@Observed//监视:使这个类中的数据变化可以被检测到从而刷新UI
export class cartInfo{

  flag:boolean//是否选中
  id:string//商品id
  url:string//图片链接
  name:string//商品名字
  price:number//商品价格
  number:number//商品数量
  stock:number//商品库存

  constructor(flag:boolean,id:string,url:string,name:string,price:number,number:number,stock:number) {
    this.flag = flag
    this.id = id
    this.url = url
    this.name = name
    this.price = price
    this.number = number
    this.stock = stock
  }
  
}

 4.渲染界面

通过获取到的数据,使用foreach渲染,并传递给子组件:

ForEach(this.cartData,(item:cartInfo,index:number)=>{
            ListItem(){
              //封装的商品子组件
              cartItem({arr:item})
            }.swipeAction({end:this.deleteCartShop(item.id)})
          })

子组件定义变量来接收:

//foreach渲染过来的数据
  @ObjectLink arr:cartInfo

 5.展示总价

展示总价:循环数组中的每一项商品的数量乘价格即可。

代码:

Text(this.cartData.reduce((acc,obj)=>acc+obj.number*obj.price,0).toString())

总结

本期内容主要是基本UI渲染,以及商品数据的渲染。

下一期我们学习对数据的操作:加减商品数量,更新购物车,删除购物车,父子数据双向同步。

  • 34
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值