HarmonyOS Next 之购物车功能开发实战

HarmonyOS Next 之购物车功能开发实战

本系列教程将详细讲解如何基于 HarmonyOS Next 和 ArkUI 框架实现完整的购物车功能,涵盖核心交互场景与高级特性。以下是各模块的实现方案:

1 商品列表展示与基础布局

功能说明

实现商品卡片式布局,包含图片、标题、价格和数量选择器。

代码实现

// CartItem.ets

@Component

export struct CartItem {

private item: CartItemData; // 商品数据对象

@Link @Watch('onCountChange') count: number;

// 数量变化监听

onCountChange() {

console.info(`商品 ${this.item.name} 数量更新为:${this.count}`);

}

build() {

Row() {

Image(this.item.image) // 商品图片

.width(80)

.height(80)

.borderRadius(8)

Column() {

Text(this.item.name) // 商品名称

.fontSize(18)

.fontColor(Color.Black)

Text(`¥${this.item.price}`) // 商品价格

.fontSize(16)

.fontColor('#FF5722')

}

.layoutWeight(1)

.margin({ left: 12 })

// 数量增减按钮

CounterComponent({ count: $count })

}

.padding(12)

.backgroundColor(Color.White)

.margin({ bottom: 8 })

.borderRadius(8)

}

}

// CounterComponent.ets(数量选择子组件)

@Component

struct CounterComponent {

@Link count: number;

build() {

Row() {

Button('-')

.onClick(() => this.count > 1 && this.count--)

Text(this.count.toString())

.margin({ left: 8, right: 8 })

Button('+')

.onClick(() => this.count++)

}

}

}

2 全选/反选与批量操作

功能说明

实现全选复选框、批量删除和实时总价计算。

代码实现

// CartPage.ets

@Entry

@Component

struct CartPage {

@State cartItems: CartItemData[] = [/* 初始数据 */];

@State isAllSelected: boolean = false;

// 计算总价

get totalPrice(): number {

return this.cartItems

.filter(item => item.selected)

.reduce((sum, item) => sum + item.price * item.count, 0);

}

// 全选/反选

toggleAllSelection() {

this.isAllSelected = !this.isAllSelected;

this.cartItems = this.cartItems.map(item => ({

...item,

selected: this.isAllSelected

}));

}

build() {

Column() {

// 全选操作栏

Row() {

Checkbox({ value: this.isAllSelected })

.onChange(() => this.toggleAllSelection())

Text('全选')

Button('删除选中')

.onClick(() => {

this.cartItems = this.cartItems.filter(item => !item.selected)

})

}

// 商品列表

List({ space: 12 }) {

ForEach(this.cartItems, (item) => {

ListItem() {

CartItem({ item: item, count: $item.count })

.onClick(() => item.selected = !item.selected)

}

})

}

.layoutWeight(1)

// 底部结算栏

Row() {

Text(`合计:¥${this.totalPrice.toFixed(2)}`)

.fontSize(20)

.fontColor('#FF5722')

Button('去结算')

.backgroundColor('#07C160')

.width(120)

}

.padding(16)

}

}

}

3 删除商品动画

功能说明

实现左滑删除动画与物理震动反馈。

代码实现

// SwipeToDelete.ets

@Component

struct SwipeToDelete {

@State translateX: number = 0;

@State isDeleting: boolean = false;

build() {

Stack() {

// 删除按钮背景

Row() {

Button($r('app.media.ic_delete'))

.onClick(() => this.isDeleting = true)

}

.width(80)

.height('100%')

.justifyContent(FlexAlign.End)

.backgroundColor('#FF3B30')

.opacity(this.translateX < -20 ? 1 : 0)

// 商品项主内容

Row() {

CartItem({ /* 商品数据 */ })

}

.translate({ x: this.translateX })

.gesture(

PanGesture({ distance: 5 })

.onActionUpdate((event: GestureEvent) => {

if (Math.abs(event.offsetX) > 20) {

this.translateX = event.offsetX;

}

})

.onActionEnd(() => {

if (this.translateX < -60) {

animateTo({ duration: 200 }, () => {

this.translateX = -200;

this.isDeleting = true;

})

} else {

animateTo({ duration: 200 }, () => this.translateX = 0)

}

})

)

}

.height(100)

.clip(true)

}

}

4 数据持久化存储

功能说明

使用 @ohos.data.storage 实现购物车本地缓存。

代码实现

// CartStorage.ets

import { storage } from '@ohos.data.storage';

const STORAGE_KEY = 'cartData';

export class CartStorage {

static async saveCart(items: CartItemData[]) {

const storage = await storage.getStorage();

await storage.set(STORAGE_KEY, JSON.stringify(items));

await storage.flush();

}

static async loadCart(): Promise {

const storage = await storage.getStorage();

const data = await storage.get(STORAGE_KEY, '[]');

return JSON.parse(data);

}

}

// 在页面中调用

aboutToAppear() {

CartStorage.loadCart().then(items => this.cartItems = items);

}

aboutToDisappear() {

CartStorage.saveCart(this.cartItems);

}

依赖项:

"dependencies": {

"@ohos.data.storage": ">=3.1.0",

"@ohos.vibrator": ">=3.1.0" // 震动反馈模块

}

权限申请:

"requestPermissions": [

{ "name": "ohos.permission.VIBRATE" }

]

相关推荐

夏侯惇为什么是曹丕的叔叔 夏侯惇为什么是曹丕的叔叔呢
mobile365官方网站立即加入

夏侯惇为什么是曹丕的叔叔 夏侯惇为什么是曹丕的叔叔呢

07-02 👁️ 3686
要工资怎么开口好?教你职场沟通技巧,老板会怎么回应?
[国足]回顾历史 2001年“刷卡”成功进世界杯
365bet开户地址

[国足]回顾历史 2001年“刷卡”成功进世界杯

08-01 👁️ 8578