鸿蒙系统自定义组件开发指南(十一):实战案例 —— 电商应用商品卡片组件

在电商应用中,商品卡片是一个非常常见的核心组件,它用于展示商品的基本信息,如商品图片、名称、价格、评分等。通过精心设计和开发一个功能完整、性能优良的商品卡片组件,可以提升电商应用的用户体验和商品展示效果,进而促进商品的销售和转化。

本实战案例将展示如何在鸿蒙系统中创建一个电商应用中的商品卡片组件,该组件集成了多种自定义组件开发技术,包括组件复合、自定义事件与回调、组件插槽等,实现了一个功能丰富、交互流畅的商品卡片展示效果。

// 商品数据接口
interface Product {
  id: string;
  title: string;
  price: number;
  originalPrice?: number;
  imageUrl: string;
  tags?: string[];
  rating: number;
  salesCount: number;
}

// 评分组件
@Component
struct ProductRating {
  rating: number = 0;
  
  build() {
    Row({ space: 4 }) {
      ForEach(new Array(5).fill(0), (_, index) => {
        Image(index < Math.floor(this.rating) ? 
             $r('app.media.ic_star_filled') : $r('app.media.ic_star_empty'))
          .width(12)
          .height(12)
      })
      
      Text(`${this.rating.toFixed(1)}`)
        .fontSize(12)
        .fontColor('#FF9500')
    }
  }
}

// 商品标签组件
@Component
struct ProductTag {
  text: string = '';
  
  build() {
    Text(this.text)
      .fontSize(10)
      .backgroundColor('#FFF0E6')
      .fontColor('#FF6E1B')
      .padding({ left: 6, right: 6, top: 2, bottom: 2 })
      .borderRadius(4)
  }
}

// 主商品卡片组件
@Component
export struct ProductCard {
  // 商品数据
  product: Product = {
    id: '',
    title: '',
    price: 0,
    imageUrl: '',
    rating: 0,
    salesCount: 0
  };
  
  // 卡片点击事件
  onCardClick?: (productId: string) => void;
  // 加入购物车事件
  onAddToCart?: (productId: string) => void;
  
  build() {
    Column() {
      // 商品图片
      Stack({ alignContent: Alignment.BottomStart }) {
        Image(this.product.imageUrl)
          .width('100%')
          .height(180)
          .objectFit(ImageFit.Cover)
          .borderRadius({ topLeft: 8, topRight: 8 })
        
        // 商品标签
        if (this.product.tags && this.product.tags.length > 0) {
          Row({ space: 4 }) {
            ForEach(this.product.tags.slice(0, 2), (tag: string) => {
              ProductTag({ text: tag })
            })
          }
          .padding(8)
        }
      }
      .width('100%')
      
      // 商品信息
      Column({ space: 6 }) {
        // 商品标题
        Text(this.product.title)
          .fontSize(14)
          .fontWeight(FontWeight.Medium)
          .maxLines(2)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
        
        // 商品价格
        Row({ space: 4 }) {
          Text(${this.product.price.toFixed(2)}`)
            .fontSize(16)
            .fontColor('#FF6E1B')
            .fontWeight(FontWeight.Bold)
          
          if (this.product.originalPrice && this.product.originalPrice > this.product.price) {
            Text(${this.product.originalPrice.toFixed(2)}`)
              .fontSize(12)
              .fontColor('#999999')
              .decoration({ type: TextDecorationType.LineThrough })
          }
        }
        
        // 评分和销量
        Row() {
          ProductRating({ rating: this.product.rating })
          
          Text(`${this.product.salesCount}人已购买`)
            .fontSize(12)
            .fontColor('#999999')
            .margin({ left: 10 })
        }
        
        // 添加到购物车按钮
        Button('加入购物车')
          .width('100%')
          .height(32)
          .fontSize(12)
          .fontWeight(FontWeight.Medium)
          .backgroundColor('#FF6E1B')
          .borderRadius(16)
          .margin({ top: 8 })
          .onClick((event) => {
            event.stopPropagation();  // 阻止冒泡,防止触发卡片点击事件
            if (this.onAddToCart) {
              this.onAddToCart(this.product.id);
            }
          })
      }
      .width('100%')
      .padding(10)
    }
    .width('100%')
    .backgroundColor(Color.White)
    .borderRadius(8)
    .shadow({ radius: 4, color: '#33000000', offsetX: 0, offsetY: 2 })
    .onClick(() => {
      if (this.onCardClick) {
        this.onCardClick(this.product.id);
      }
    })
  }
}

// 使用商品卡片组件
@Entry
@Component
struct ProductListPage {
  @State products: Product[] = [
    {
      id: '1',
      title: '鸿蒙智能手表 GT3 Pro 钛金属表带',
      price: 2488,
      originalPrice: 2699,
      imageUrl: '/assets/products/watch.jpg',
      tags: ['新品', '限时优惠'],
      rating: 4.9,
      salesCount: 3205
    },
    {
      id: '2',
      title: '鸿蒙智能手机 P50 Pro 8GB+256GB 曜金黑',
      price: 5988,
      originalPrice: 6488,
      imageUrl: '/assets/products/phone.jpg',
      tags: ['热销'],
      rating: 4.8,
      salesCount: 15230
    },
    {
      id: '3',
      title: '鸿蒙平板电脑 MatePad Pro 10.8英寸 8GB+256GB',
      price: 3799,
      imageUrl: '/assets/products/tablet.jpg',
      tags: ['教育优惠'],
      rating: 4.7,
      salesCount: 2158
    }
  ];
  
  build() {
    Column() {
      Text('商品列表')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 20, bottom: 16 })
      
      Grid() {
        ForEach(this.products, (product: Product) => {
          GridItem() {
            ProductCard({
              product: product,
              onCardClick: (productId) => {
                console.info(`点击商品ID: ${productId}`);
                // 可以在这里导航到商品详情页
              },
              onAddToCart: (productId) => {
                console.info(`添加商品到购物车: ${productId}`);
                // 可以在这里实现添加购物车逻辑
              }
            })
          }
        })
      }
      .columnsTemplate('1fr 1fr')
      .columnsGap(12)
      .rowsGap(12)
      .width('100%')
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F5F5F5')
    .padding(16)
  }
}

在上述代码中,首先定义了一个商品数据接口 Product,用于描述商品的各项属性。接着,创建了两个基础组件:ProductRating(评分组件)和 ProductTag(商品标签组件)。ProductRating 组件用于展示商品的评分星星和具体评分数值,根据传入的评分值动态地显示填充星星和空星星的数量;ProductTag 组件用于展示商品的标签信息,如“新品”“限时优惠”等。

然后,开发了主商品卡片组件 ProductCard,它是一个复合组件,组合了商品图片、商品标签、商品信息(包括标题、价格、评分和销量)以及加入购物车按钮等多个部分。在 ProductCard 组件中,通过使用 previously defined 组件(如 ProductRating 和 ProductTag)来构建完整的商品卡片布局,并且定义了卡片点击事件(onCardClick)和加入购物车事件(onAddToCart),使得该组件具有良好的交互性。当用户点击商品卡片时,会触发 onCardClick 回调函数,可以用于跳转到商品详情页面;当用户点击加入购物车按钮时,会触发 onAddToCart 回调函数,用于执行添加商品到购物车的逻辑。

最后,在 ProductListPage 页面中使用 ProductCard 组件来展示一个商品列表。通过 ForEach 循环遍历商品数据数组,为每个商品创建一个 ProductCard 组件实例,并传入相应的商品数据以及事件回调函数,实现动态的商品列表展示。在页面布局上,使用 Grid 布局将商品列表以两列的形式展示,每个商品卡片之间具有一定的间距,使得整个商品列表页面整齐、美观,便于用户浏览和选择商品。

通过这个实战案例,我们可以看到鸿蒙系统自定义组件开发技术在实际应用中的强大功能和灵活运用。从基础组件的创建到复合组件的组合,再到事件回调和组件插槽的使用,各个环节紧密配合,最终构建出了一个功能完善、交互良好的商品卡片组件。在实际的电商应用开发中,可以根据具体的业务需求和设计规范,进一步扩展和定制该组件,以满足不同的商品展示和交互要求。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐