在鸿蒙(HarmonyOS)生态中使用 DevEco Studio 实现购物应用的基础功能(如商品展示、购物车、订单管理),可以通过以下步骤完成。这里以 ArkTS(推荐语言)为例,提供核心代码和实现逻辑。
1. 基础功能实现
1.1 商品列表展示
功能需求
- 从本地或网络加载商品数据。
- 使用
List组件展示商品图片、名称、价格等信息。
代码实现
typescript
复制
// 商品数据类型
interface Product {
id: number;
name: string;
price: number;
image: string; // 图片资源路径或URL
}
@Entry
@Component
struct ProductList {
// 模拟商品数据
@State products: Product[] = [
{ id: 1, name: "华为Mate 60", price: 5999, image: "common/images/mate60.jpg" },
{ id: 2, name: "FreeBuds Pro", price: 999, image: "common/images/freebuds.jpg" },
{ id: 3, name: "Watch GT 4", price: 1499, image: "common/images/watch.jpg" },
];
build() {
List({ space: 10 }) {
ForEach(this.products, (product: Product) => {
ListItem() {
Row() {
Image(product.image)
.width(100)
.height(100)
.borderRadius(8)
Column() {
Text(product.name)
.fontSize(16)
.fontWeight(FontWeight.Bold)
Text(`¥${product.price}`)
.fontColor(Color.Red)
}.margin({ left: 10 })
}
.padding(10)
.width('100%')
}
})
}
.width('100%')
.height('100%')
}
}
1.2 购物车功能
1. 购物车数据模型
创建购物车项数据类 CartItem.java:
java
public class CartItem {
private Product product;
private int quantity;
public CartItem(Product product, int quantity) {
this.product = product;
this.quantity = quantity;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public void increaseQuantity() {
this.quantity++;
}
public void decreaseQuantity() {
if (quantity > 1) {
this.quantity--;
}
}
public double getSubtotal() {
return product.getPrice() * quantity;
}
}
2. 购物车管理类
创建单例模式的购物车管理类 CartManager.java:
java
public class CartManager {
private static CartManager instance;
private List<CartItem> cartItems;
private Context context;
private CartManager() {
cartItems = new ArrayList<>();
}
public static CartManager getInstance() {
if (instance == null) {
synchronized (CartManager.class) {
if (instance == null) {
instance = new CartManager();
}
}
}
return instance;
}
public void init(Context context) {
this.context = context;
// 从本地数据库或缓存加载购物车数据
loadCartFromStorage();
}
// 添加商品到购物车
public void addProduct(Product product, int quantity) {
for (CartItem item : cartItems) {
if (item.getProduct().getId().equals(product.getId())) {
item.increaseQuantity();
saveCartToStorage();
return;
}
}
cartItems.add(new CartItem(product, quantity));
saveCartToStorage();
}
// 从购物车移除商品
public void removeProduct(Product product) {
cartItems.removeIf(item -> item.getProduct().getId().equals(product.getId()));
saveCartToStorage();
}
// 更新购物车中商品数量
public void updateProductQuantity(Product product, int quantity) {
for (CartItem item : cartItems) {
if (item.getProduct().getId().equals(product.getId())) {
if (quantity <= 0) {
cartItems.remove(item);
} else {
item.setQuantity(quantity);
}
saveCartToStorage();
break;
}
}
}
// 获取购物车所有商品
public List<CartItem> getCartItems() {
return new ArrayList<>(cartItems);
}
// 获取购物车商品总数
public int getTotalItemCount() {
return cartItems.stream().mapToInt(CartItem::getQuantity).sum();
}
// 获取购物车商品总价
public double getTotalAmount() {
return cartItems.stream().mapToDouble(CartItem::getSubtotal).sum();
}
// 保存购物车到存储
private void saveCartToStorage() {
if (context != null) {
// 使用鸿蒙的Preferences存储简单数据
Preferences preferences = Preferences.create(context, "shopping_cart");
preferences.putString("cart_items", new Gson().toJson(cartItems));
preferences.flush();
}
}
// 从存储加载购物车
private void loadCartFromStorage() {
if (context != null) {
Preferences preferences = Preferences.create(context, "shopping_cart");
String cartJson = preferences.getString("cart_items", "[]");
cartItems = new Gson().fromJson(cartJson, new TypeToken<List<CartItem>>() {
}.getType());
if (cartItems == null) {
cartItems = new ArrayList<>();
}
}
}
}
3. 购物车页面设计
创建购物车页面 CartAbility.java 及其布局文件 cart_layout.xml:
xml
<!-- cart_layout.xml -->
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical">
<!-- 购物车标题栏 -->
<DirectionalLayout
ohos:height="56vp"
ohos:width="match_parent"
ohos:background="#FFFFFF"
ohos:orientation="horizontal"
ohos:padding="16vp">
<Text
ohos:height="match_content"
ohos:width="match_content"
ohos:text="购物车"
ohos:text_color="#333333"
ohos:text_size="18sp"
ohos:text_weight="bold"/>
</DirectionalLayout>
<!-- 购物车商品列表 -->
<ListContainer
ohos:id="$+id/cart_list"
ohos:height="0vp"
ohos:width="match_parent"
ohos:layout_weight="1"/>
<!-- 空购物车提示 -->
<DirectionalLayout
ohos:id="$+id/empty_cart_container"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical"
ohos:visibility="gone">
<Image
ohos:height="120vp"
ohos:width="120vp"
ohos:image_src="$media:empty_cart"/>
<Text
ohos:height="wrap_content"
ohos:width="wrap_content"
ohos:margin="top=24vp"
ohos:text="购物车空空如也"
ohos:text_color="#999999"
ohos:text_size="16sp"/>
<Text
ohos:height="wrap_content"
ohos:width="wrap_content"
ohos:margin="top=8vp"
ohos:text="快去挑选喜欢的商品吧"
ohos:text_color="#999999"
ohos:text_size="14sp"/>
<Button
ohos:id="$+id/go_shopping_btn"
ohos:height="48vp"
ohos:width="200vp"
ohos:background="#007DFF"
ohos:border_radius="24vp"
ohos:margin="top=32vp"
ohos:text="去购物"
ohos:text_color="white"
ohos:text_size="16sp"/>
</DirectionalLayout>
<!-- 底部结算栏 -->
<DirectionalLayout
ohos:height="72vp"
ohos:width="match_parent"
ohos:background="#FFFFFF"
ohos:orientation="horizontal"
ohos:padding="16vp 0vp">
<CheckBox
ohos:id="$+id/select_all"
ohos:height="match_content"
ohos:width="match_content"
ohos:checked="true"/>
<Text
ohos:height="match_content"
ohos:width="wrap_content"
ohos:margin="left=8vp"
ohos:text="全选"
ohos:text_color="#333333"
ohos:text_size="14sp"/>
<DirectionalLayout
ohos:height="match_parent"
ohos:width="0vp"
ohos:layout_weight="1"
ohos:alignment="center_vertical"
ohos:orientation="horizontal"
ohos:padding="left=24vp">
<Text
ohos:height="wrap_content"
ohos:width="wrap_content"
ohos:text="合计:"
ohos:text_color="#333333"
ohos:text_size="14sp"/>
<Text
ohos:id="$+id/total_amount"
ohos:height="wrap_content"
ohos:width="wrap_content"
ohos:margin="left=4vp"
ohos:text="¥0.00
1.3 订单提交(模拟HTTP请求)
功能需求
- 提交购物车数据到后端(模拟API)。
- 使用
@ohos.net.http发送网络请求。
代码实现
typescript
复制
import http from '@ohos.net.http';
// 模拟订单提交
async function submitOrder(cartItems: CartItem[]): Promise<boolean> {
const httpRequest = http.createHttp();
const url = "https://api.example.com/orders";
const data = JSON.stringify({ items: cartItems });
try {
const response = await httpRequest.request(
url,
{ method: "POST", header: { "Content-Type": "application/json" }, extraData: data }
);
return response.responseCode === 200;
} catch (error) {
console.error("订单提交失败:", error);
return false;
}
}
// 在购物车页面调用
Button("提交订单")
.onClick(async () => {
const success = await submitOrder(this.cartItems);
if (success) {
alert("订单提交成功!");
this.cartItems = []; // 清空购物车
}
})
2. 进阶优化
2.1 数据持久化
- 使用
@ohos.data.storage存储购物车数据,避免页面刷新后丢失:
typescript
复制
import storage from '@ohos.data.storage';
const storageKey = "cartData";
const context = getContext(this);
// 保存购物车数据
function saveCart(items: CartItem[]) {
const storage = storage.getStorageSync(context, "CartDB");
storage.putSync(storageKey, JSON.stringify(items));
storage.flushSync();
}
// 读取购物车数据
function loadCart(): CartItem[] {
const storage = storage.getStorageSync(context, "CartDB");
const data = storage.getSync(storageKey, "[]");
return JSON.parse(data);
}
2.2 多设备协同
- 通过
分布式数据管理实现手机/平板同步购物车:
typescript
复制
import distributedData from '@ohos.data.distributedData';
// 初始化分布式数据
const kvManager = distributedData.createKVManager({
bundleName: "com.example.shop",
options: { syncPolicy: "DEVICE_COLLABORATION" }
});
// 同步购物车数据
async function syncCart() {
const kvStore = await kvManager.getKVStore("cartStore");
await kvStore.put("cartItems", JSON.stringify(this.cartItems));
}
3. 运行效果
- 商品列表页:
example.com/product-lis… - 购物车页:
example.com/cart.png
4. 完整项目结构
markdown
复制
resources/
├── base/
│ ├── element/ // 字符串和样式
│ └── media/ // 图片资源
src/
├── main/
│ ├── ets/
│ │ ├── pages/
│ │ │ ├── ProductList.ets // 商品列表
│ │ │ ├── Cart.ets // 购物车逻辑
│ │ │ └── Order.ets // 订单提交
│ │ └── utils/
│ │ ├── http.ets // 网络请求封装
│ │ └── storage.ets // 数据持久化
│ └── resources/ // 资源文件
5. 常见问题
-
图片加载失败
- 确保图片路径正确,或使用网络图片时添加
ohos.permission.INTERNET权限。
- 确保图片路径正确,或使用网络图片时添加
-
购物车数据不同步
- 检查
@State和@Link的使用,或改用AppStorage全局状态管理。
- 检查
-
HTTP请求报错
- 在
module.json5中声明网络权限:
json 复制 { "requestPermissions": [ { "name": "ohos.permission.INTERNET" } ] } - 在