鸿蒙商城列表案例实操

一、构建自定义组件Header用来封装页头

1.1首先我们在编译器中先创建一个ArkTS文件,命名为Header

如下所示:

@Component
struct Header {
  build() {
  }
}

1.2创建一个ArkTS文件命名为ImagePage7

@Entry
@Component
struct ImagePage7 {

  build() {

}
}

1.3设置Row布局,添加image,利用space设置间距,添加blank组件,填满剩余空间。

build() {
  Row({space:10}){
    Image($r('app.media.fanhuijiantou'))
      .width(30)
    Text(this.title)
      .fontSize(30)
      .fontWeight(FontWeight.Bold)  //字体加粗
    Blank() //占满剩余空间
    Image($r('app.media.shuaxinanniu'))
      .width(30)
  }
  .width('100%')
  .padding(20)
}

1.4定义一个title变量标题,传入数据。

struct Header {
  title:string
  build() {
    Row({space:10}){
      Image($r('app.media.fanhuijiantou'))
        .width(30)
      Text(this.title)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)  //字体加粗
      Blank() //占满剩余空间
      Image($r('app.media.shuaxinanniu'))
        .width(30)
    }
    .width('100%')
    .padding(20)
  }
}

1.5我们对自定义Header组件进行导出工作

export default struct Header {
  title:string
  build() {
    Row({space:10}){
      Image($r('app.media.fanhuijiantou'))
        .width(30)
      Text(this.title)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)  //字体加粗
      Blank() //占满剩余空间
      Image($r('app.media.shuaxinanniu'))
        .width(30)
    }
    .width('100%')
    .padding(20)
  }
}

1.6我们在ImagePage7里面设置column容器

struct Image7

struct Image7Page {
  build() {
    Row(){
      Column({space:10}) {
        Header({title:'商品列表'})


    Row(){
     
Column({space:10}) {
       
Header({title:'商品列表'})

导包:

//import导入Header
//加上default Header就不能再加上{}
import Header from '../components/Header'

Export对外有一个访问接口,在header的导出方法中添加default则不用加上{}。

@Component
 export default struct Header {
  title:string

1.7添加属性,设置宽度和高度

.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)

二、循环渲染

2.1定义一个ImageItem类,实例化商品名称,图片,价格,折扣。

//声明一个类ImageItem类
class ImageItem{
  name:string
  image:ResourceStr
  price:number
  discount:number
  //修改里面的值
  setName(name:string){
    // this.name=this.name+name
    this.name=name
  }
  getName(){
    return this.name
  }

2.2定义构造函数传参

//定义一个构造函数
constructor(name:string,image:ResourceStr, price:number, discount?:number) {
  //?:非必选,设置可选参数
  this.name=name
  this.image=image
  this.price=price
  this.discount=discount
}

2.3定义数组

struct Image7Page {
  //定义数组
  private list:Array<ImageItem>=[
    new ImageItem('华为Mate60',$r('app.media.huaweiMate60'),6999,500),
    new ImageItem('华为book',$r('app.media.huaweiBook'),13999),
    new ImageItem('WatchGT4',$r('app.media.WatchGT4'),1438),
    new ImageItem('FreeBuds',$r('app.media.FreeBuds'),1499),
    new ImageItem('Mate X5',$r('app.media.matex5'),12999),
    new ImageItem('WatchGT4',$r('app.media.WatchGT4'),1438),
    new ImageItem('FreeBuds',$r('app.media.FreeBuds'),1499),
    new ImageItem('Mate X5',$r('app.media.matex5'),12999)
  ]

2.4创建row组件传子组件image

build() {
  Row(){
    Column({space:10}){
      Header({title:'商品列表'})
      Row(){
        Image(item.image)
          .width(100)
        Column(){
          Text(item.name)
            .fontSize(20)
            .fontWeight(FontWeight.Bold)

2.5用foreach进行渲染

ForEach(this.list,(item:ImageItem)=>{
  Row(){
    Image(item.image)
      .width(100)
    Column(){
      Text(item.name)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      Text(`原价:¥ ${item.price}`)

三、条件渲染

3.1在column中写入text组件

Column(){
  Text(item.name)
    .fontSize(20)
    .fontWeight(FontWeight.Bold)
  Text(`原价:¥ ${item.price}`)
  Text(`折扣价:¥ ${item.price-item.discount}`)
  Text(`补贴:¥ ${item.discount}`)

3.2用if else判断语句

if (item.discount){
    Text(`原价:¥${item.price}`)
      // .fontSize(18)
      .fontColor('#ccc')
      .decoration({type:TextDecorationType.LineThrough})
    Text(`折扣价:¥${item.price - item.discount}`)
      .priceText()
    Text(`补贴:¥${item.discount}`)
      .priceText()
  }else {
    Text('原价:¥'+item.price)
      .priceText()
      // .fontSize(16)
      // .fontColor('#F36')
  }
}

四、List组件

4.1添加list

List( {space:10}){
  ForEach(this.list,(item:ImageItem)=>{
    if (item.discount){
      Text(`原价:¥ ${item.price}`)
        .fontColor('#ccc')
        .decoration({type:TextDecorationType.LineThrough})
      Text(`折扣价:¥ ${item.price-item.discount}`)
        .fontSize(16)
        .fontColor('#F36')
      Text(`补贴:¥ ${item.discount}`)
    }else{
      Text('原价:¥'+item.price)
        .fontSize(16)
        .fontColor('#F36')
    }
  }

4.2使用list子组件listitem

List( {space:10}){
  ForEach(this.list,(item:ImageItem)=>{
    ListItem(){
      Row(){
        Image(item.image)
          .width(100)
        Column(){
          //标题名字固定
          Text(item.name)
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
          //用if渲染
          if (item.discount){
            Text(`原价:¥ ${item.price}`)
              .fontColor('#ccc')
              .decoration({type:TextDecorationType.LineThrough})
            Text(`折扣价:¥ ${item.price-item.discount}`)
              .fontSize(16)
              .fontColor('#F36')
            Text(`补贴:¥ ${item.discount}`)
              .fontSize(16)
              .fontColor('#F36')
          }else{
            Text('原价:¥'+item.price)
              .fontSize(16)
              .fontColor('#F36')
          }
        }

4.3设置键值,设置为一标识

ForEach(this.list,(item:ImageItem)=>{   //重复渲染
  ListItem(){
    itemCardToal(item)
  }
},(item:ImageItem) => item.name)//name是唯一标识

4.4进行美化

build() {
  Row(){
    Column({space:10}){
      Header({title:'商品列表'})
      List( {space:10}){
        ForEach(this.list,(item:ImageItem)=>{
          ListItem(){
            Row(){
              Image(item.image)
                .width(100)
              Column(){
                //标题名字固定
                Text(item.name)
                  .fontSize(20)
                  .fontWeight(FontWeight.Bold)
                //用if渲染
                if (item.discount){
                  Text(`原价:¥ ${item.price}`)
                    .fontColor('#ccc')
                    .decoration({type:TextDecorationType.LineThrough})
                  Text(`折扣价:¥ ${item.price-item.discount}`)
                    .fontSize(16)
                    .fontColor('#F36')
                  Text(`补贴:¥ ${item.discount}`)
                    .fontSize(16)
                    .fontColor('#F36')
                }else{
                  Text('原价:¥'+item.price)
                    .fontSize(16)
                    .fontColor('#F36')
                }
              }
              .height('100%')
              .alignItems(HorizontalAlign.Start)
            }//设置圆角边框大小,背景颜色
            .height(120)
            .width('100%')
            .borderRadius(20)
            .backgroundColor('#FFF')
            .padding(10)
          }
        },(item:ImageItem)=>item.name) //键值生成规则 重复渲染 设置唯一标识
      }
      .layoutWeight(1)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#EFEFEF')
    .padding(20)
  }
}

五、自定义构建函数

5.1创建自定义函数itemCard

@Builder ItemCard(item:ImageItem){
  Row(){
    Image(item.image)
      .width(100)
    Column(){
      Text(item.name)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      if (item.discount){
        Text(`原价:¥ ${item.price}`)
          .fontColor('#ccc')
          .decoration({type:TextDecorationType.LineThrough})
        Text(`折扣价:¥ ${item.price-item.discount}`)
          .fontSize(16)
          .fontColor('#F36')
        Text(`补贴:¥ ${item.discount}`)
          .fontSize(16)
          .fontColor('#F36')
      }else{
        Text('原价:¥'+item.price)
          .fontSize(16)
          .fontColor('#F36')
      }
    }
    .height('100%')
    .alignItems(HorizontalAlign.Start)
  }//设置row的宽度和高度,以及圆角边框大小,背景颜色
  .height(120)
  .width('100%')
  .borderRadius(20)
  .backgroundColor('#FFF')
  .padding(10)

5.2再回到listltem里面直接调用itemcard

List( {space:10}){
  ForEach(this.list,(item:ImageItem)=>{
    ListItem(){
      // 直接调用自定义函数ItemCard
      this.ItemCard(item)

六、@Style装饰器

6.1创建fillScreen进行封装

@Styles function fillScreen1(){
  .width('100%')
  .height('100%')
  .backgroundColor('#EFEFEF')
  .padding(20)
}

6.2对row调用

@Builder function itemCardToal(item:ImageItem){
  Row(){
    Image(item.image)
      .width(100)
    Column(){
      Text(item.name)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      if (item.discount){
        Text(`原价:¥${item.price}`)
          // .fontSize(18)
          .fontColor('#ccc')
          .decoration({type:TextDecorationType.LineThrough})
        Text(`折扣价:¥${item.price - item.discount}`)
          .priceText()
        Text(`补贴:¥${item.discount}`)
          .priceText()
      }else {
        Text('原价:¥'+item.price)
          .priceText()
          // .fontSize(16)
          // .fontColor('#F36')
      }
    }.alignItems(HorizontalAlign.Start)  //设置水平居中左对齐
     .fillScreen()
  }//设置row的宽度高度和圆角边框的大小和背景颜色
  .fillScreen()
}

如上所示,对column也就进行调用

七、@Extend装饰器

7.1定义pricetext写入字体大小

@Extend(Text)function priceText(){
  .fontSize(16)
  .fontColor('#F36')
}

7.2调用扩展样式

@Builder function  ItemCardTotal(item:ImageItem){
  Row(){
    Image(item.image)
      .width(100)
    Column(){
      Text(item.name)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      if (item.discount){
        Text(`原价:¥ ${item.price}`)
          .fontColor('#ccc')
          .decoration({type:TextDecorationType.LineThrough})
        Text(`折扣价:¥ ${item.price-item.discount}`)
          .priceText()
        Text(`补贴:¥ ${item.discount}`)
          .priceText()
      }else{
        Text('原价:¥'+item.price)
          .priceText()
      }
    }.alignItems(HorizontalAlign.Start)
    .fillScreen1()

  }
  .fillScreen()

}

八、整体代码如下:

//import导入Header
//加上default Header就不能再加上{}
import Header from '../components/Header'
//声明一个类ImageItem类
class ImageItem{
  name:string
  image:ResourceStr
  price:number
  discount:number
  //修改里面的值
  setName(name:string){
    // this.name=this.name+name
    this.name=name
  }
  getName(){
    return this.name
  }
  //定义一个构造函数
  constructor(name:string,image:ResourceStr, price:number, discount?:number) {
    //?:非必选,设置可选参数
    this.name=name
    this.image=image
    this.price=price
    this.discount=discount
  }
}
//全局自定义构建函数需要加funcation函数,所以build里就不需要this来进行调用了
@Builder function itemCardToal(item:ImageItem){
  Row(){
    Image(item.image)
      .width(100)
    Column(){
      Text(item.name)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      if (item.discount){
        Text(`原价:¥${item.price}`)
          // .fontSize(18)
          .fontColor('#ccc')
          .decoration({type:TextDecorationType.LineThrough})
        Text(`折扣价:¥${item.price - item.discount}`)
          .priceText()
        Text(`补贴:¥${item.discount}`)
          .priceText()
      }else {
        Text('原价:¥'+item.price)
          .priceText()
          // .fontSize(16)
          // .fontColor('#F36')
      }
    }.alignItems(HorizontalAlign.Start)  //设置水平居中左对齐
     .fillScreen()
  }//设置row的宽度高度和圆角边框的大小和背景颜色
  .fillScreen()
}
@Styles function fillScreen(){
  .height(120)
  .width('100%')
  .borderRadius(20)  //设置圆角
  .backgroundColor('#FFF')
  .padding(10)
}
@Styles function fillScreen1(){
  .width('100%')
  .height('100%')
  .backgroundColor('#EFEFEF')
  .padding(20)
}
@Extend(Text)function priceText(){
  .fontSize(16)
  .fontColor('#F36')
}
@Entry
@Component
struct Image7Page {
  //定义数组
  private list:Array<ImageItem>=[
    new ImageItem('华为Mate60',$r('app.media.huaweiMate60'),6999,500),
    new ImageItem('华为book',$r('app.media.huaweiBook'),13999),
    new ImageItem('WatchGT4',$r('app.media.WatchGT4'),1438),
    new ImageItem('FreeBuds',$r('app.media.FreeBuds'),1499),
    new ImageItem('Mate X5',$r('app.media.matex5'),12999),
    new ImageItem('WatchGT4',$r('app.media.WatchGT4'),1438),
    new ImageItem('FreeBuds',$r('app.media.FreeBuds'),1499),
    new ImageItem('Mate X5',$r('app.media.matex5'),12999)
  ]
  //如果不传参数,直接默认值给0
  test(name:string,age:number=0){
    console.log('name',name,'age',age)
  }
  build() {
    Row(){
      Column({space:10}) {
        Header({title:'商品列表'})
        List(){
          ForEach(this.list,(item:ImageItem)=>{   //重复渲染
            ListItem(){
              itemCardToal(item)
            }
          },(item:ImageItem) => item.name)//name是唯一标识
        }.layoutWeight(1)
      }.fillScreen1()
    }
  }
}

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值