跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
TypeScript大前端

鸿蒙电商购物车全栈实战:用户管理、商品列表与购物车实现

鸿蒙电商购物车全栈项目核心模块实现,涵盖用户注册登录、信息管理、商品列表展示搜索及购物车增删改查功能。通过分层架构设计,封装单例工具类处理业务逻辑,结合 ArkTS 组件化开发实现界面交互,确保数据流转安全与响应速度,为后续订单与支付模块奠定基础。

虚拟内存发布于 2026/3/29更新于 2026/9/239 浏览
鸿蒙电商购物车全栈实战:用户管理、商品列表与购物车实现

鸿蒙电商购物车全栈实战:用户管理、商品列表与购物车实现

项目架构图

本次实战聚焦于鸿蒙电商购物车全栈项目的核心业务模块,深入讲解用户管理、商品列表及购物车功能的实现逻辑。我们将基于现有架构,完成基础功能的落地,确保数据流转的安全性与界面的响应速度。

一、用户管理基础与架构

用户管理是电商系统的基石,主要涵盖注册、登录、信息维护及权限控制。在架构设计上,我们采用分层模式,将业务逻辑、数据存储、接口设计与界面渲染解耦,便于后期维护与扩展。

  • 用户服务层:处理核心业务逻辑;
  • 用户数据层:负责数据的持久化存储;
  • 用户接口层:定义对外交互标准;
  • 用户展示层:负责 UI 渲染与交互反馈。

二、用户管理实战

1. 用户注册实现

注册功能需要处理邮箱验证与密码加密。我们利用单例模式封装工具类,避免重复初始化资源。

entry/src/main/ets/utils/UserRegistrationUtil.ets

import user from '@ohos/user';

// 用户注册工具类
export class UserRegistrationUtil {
  private static instance: UserRegistrationUtil | null = null;
  private userHelper: user.UserHelper | null = null;

  // 单例模式
  static getInstance(): UserRegistrationUtil {
    if (!UserRegistrationUtil.instance) {
      UserRegistrationUtil.instance = new UserRegistrationUtil();
    }
    return UserRegistrationUtil.instance;
  }

  // 初始化用户注册
  async init(): Promise<void> {
    if (!this.userHelper) {
      this.userHelper = user.createUserHelper();
    }
  }

  // 用户注册
  async register(email: string, password: string): Promise<user.UserRegistrationResult> {
    if (!this.userHelper) {
      return null;
    }
    const result = await this.userHelper.register(email, password);
    return result;
  }

  // 发送验证码
  async sendVerificationCode(email: string): Promise<user.SendVerificationCodeResult> {
    if (!this.userHelper) {
      return null;
    }
    const result = await this.userHelper.sendVerificationCode(email);
    return result;
  }
}

在页面中,我们通过状态管理绑定输入框,并在点击事件触发工具类方法。注意验证码发送需校验邮箱格式,防止无效请求。

entry/src/main/ets/pages/RegistrationPage.ets

import { UserRegistrationUtil } from '../utils/UserRegistrationUtil';

@Entry
@Component
struct RegistrationPage {
  @State email: string = '';
  @State password: string = '';
  @State verificationCode: string = '';

  build() {
    Column({ space: 16 }) {
      InputComponent({
        placeholder: '请输入邮箱',
        value: this.email,
        onChange: (value: string) => {
          this.email = value;
        },
        type: InputType.Email
      });
      InputComponent({
        placeholder: '请输入密码',
        value: this.password,
        onChange: (value: string) => {
          this.password = value;
        },
        type: InputType.Password
      });
      InputComponent({
        placeholder: '请输入验证码',
        value: this.verificationCode,
        onChange: (value: string) => {
          this.verificationCode = value;
        },
        type: InputType.Normal
      });
      ButtonComponent({
        text: '发送验证码',
        onClick: async () => {
          await this.sendVerificationCode();
        },
        disabled: !this.email
      });
      ButtonComponent({
        text: '注册',
        onClick: async () => {
          await this.register();
        },
        disabled: !this.email || !this.password || !this.verificationCode
      });
    }
      .width('100%')
      .height('100%')
      .padding(16)
      .backgroundColor('#F5F5F5');
  }

  aboutToAppear() {
    // 初始化用户注册
    UserRegistrationUtil.getInstance().init();
  }

  async sendVerificationCode(): Promise<void> {
    const result = await UserRegistrationUtil.getInstance().sendVerificationCode(this.email);
    if (result.success) {
      promptAction.showToast({ message: '验证码发送成功' });
    } else {
      promptAction.showToast({ message: '验证码发送失败' });
    }
  }

  async register(): Promise<void> {
    const result = await UserRegistrationUtil.getInstance().register(this.email, this.password);
    if (result.success) {
      promptAction.showToast({ message: '注册成功' });
      router.pushUrl({ url: '/pages/LoginPage' });
    } else {
      promptAction.showToast({ message: '注册失败' });
    }
  }
}
2. 用户登录与信息维护

登录逻辑类似注册,但侧重于身份校验。登录后跳转首页,并支持密码找回。用户信息管理页则允许修改昵称、头像及密码,所有操作均通过工具类异步执行,避免阻塞主线程。

(此处省略部分代码以保持篇幅,实际项目中需完整实现 UserLoginUtil 与 UserInformationManagementUtil)

三、商品列表实战

商品模块需要高效展示数据并提供搜索能力。列表页采用 ListComponent 进行滚动优化,详情页则展示完整信息与购买入口。

1. 商品列表与搜索

entry/src/main/ets/utils/ProductListUtil.ets

import product from '@ohos/product';

export class ProductListUtil {
  private static instance: ProductListUtil | null = null;
  private productHelper: product.ProductHelper | null = null;

  static getInstance(): ProductListUtil {
    if (!ProductListUtil.instance) {
      ProductListUtil.instance = new ProductListUtil();
    }
    return ProductListUtil.instance;
  }

  async init(): Promise<void> {
    if (!this.productHelper) {
      this.productHelper = product.createProductHelper();
    }
  }

  async getProductList(): Promise<Array<product.Product>> {
    if (!this.productHelper) {
      return [];
    }
    const result = await this.productHelper.getProductList();
    return result;
  }

  async searchProduct(keyword: string): Promise<Array<product.Product>> {
    if (!this.productHelper) {
      return [];
    }
    const result = await this.productHelper.searchProduct(keyword);
    return result;
  }
}

页面端通过监听输入框变化触发搜索,同时利用 onItemClick 快速进入详情。

2. 商品详情与加购

详情页不仅展示信息,还集成了数量选择器与加购按钮。这里的关键在于将商品 ID 与数量传递给购物车模块。

entry/src/main/ets/pages/ProductDetailPage.ets

import { ProductDetailUtil } from '../utils/ProductDetailUtil';
import { CartManagementUtil } from '../utils/CartManagementUtil';

@Entry
@Component
struct ProductDetailPage {
  @State product: product.Product | null = null;
  @State quantity: number = 1;
  @State productId: number = 0;

  build() {
    Column({ space: 16 }) {
      if (this.product) {
        Image(this.product.avatarUrl)
          .width('100%')
          .height(240)
          .objectFit(ImageFit.Cover)
          .borderRadius(8);
        Text(this.product.name)
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .textColor('#000000');
        Text(this.product.description)
          .fontSize(14)
          .textColor('#666666')
          .maxLines(5)
          .textOverflow({ overflow: TextOverflow.Ellipsis });
        Text(`¥${this.product.price}`)
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
          .textColor('#FF0000');
        Row({ space: 16 }) {
          Text('数量:').fontSize(14).textColor('#000000');
          ButtonComponent({
            text: '-',
            onClick: () => {
              if (this.quantity > 1) {
                this.quantity--;
              }
            },
            disabled: this.quantity <= 1
          });
          Text(`${this.quantity}`).fontSize(14).textColor('#000000');
          ButtonComponent({
            text: '+',
            onClick: () => {
              this.quantity++;
            },
            disabled: this.quantity >= 10
          });
        }
          .width('100%')
          .height('auto')
          .justifyContent(FlexAlign.Center);
        ButtonComponent({
          text: '添加到购物车',
          onClick: async () => {
            await this.addToCart();
          },
          disabled: !this.product
        });
      }
    }
      .width('100%')
      .height('100%')
      .padding(16)
      .backgroundColor('#F5F5F5');
  }

  aboutToAppear() {
    ProductDetailUtil.getInstance().init();
    CartManagementUtil.getInstance().init();
    this.getProductDetail();
  }

  async getProductDetail(): Promise<void> {
    const params = router.getParams() as { productId: number };
    this.productId = params.productId;
    this.product = await ProductDetailUtil.getInstance().getProductDetail(this.productId);
  }

  async addToCart(): Promise<void> {
    const result = await CartManagementUtil.getInstance().addToCart(this.productId, this.quantity);
    if (result.success) {
      promptAction.showToast({ message: '添加到购物车成功' });
    } else {
      promptAction.showToast({ message: '添加到购物车失败' });
    }
  }
}

四、购物车管理实战

购物车是交易前的最后一道关卡,需支持数量的实时调整与商品移除。

1. 购物车工具类封装

entry/src/main/ets/utils/CartManagementUtil.ets

import cart from '@ohos/cart';

export class CartManagementUtil {
  private static instance: CartManagementUtil | null = null;
  private cartHelper: cart.CartHelper | null = null;

  static getInstance(): CartManagementUtil {
    if (!CartManagementUtil.instance) {
      CartManagementUtil.instance = new CartManagementUtil();
    }
    return CartManagementUtil.instance;
  }

  async init(): Promise<void> {
    if (!this.cartHelper) {
      this.cartHelper = cart.createCartHelper();
    }
  }

  async getCartList(): Promise<Array<cart.CartItem>> {
    if (!this.cartHelper) {
      return [];
    }
    const result = await this.cartHelper.getCartList();
    return result;
  }

  async addToCart(productId: number, quantity: number): Promise<cart.AddToCartResult> {
    if (!this.cartHelper) {
      return null;
    }
    const result = await this.cartHelper.addToCart(productId, quantity);
    return result;
  }

  async modifyCartItemQuantity(cartItemId: number, quantity: number): Promise<cart.ModifyCartItemQuantityResult> {
    if (!this.cartHelper) {
      return null;
    }
    const result = await this.cartHelper.modifyCartItemQuantity(cartItemId, quantity);
    return result;
  }

  async deleteCartItem(cartItemId: number): Promise<cart.DeleteCartItemResult> {
    if (!this.cartHelper) {
      return null;
    }
    const result = await this.cartHelper.deleteCartItem(cartItemId);
    return result;
  }

  async clearCart(): Promise<cart.ClearCartResult> {
    if (!this.cartHelper) {
      return null;
    }
    const result = await this.cartHelper.clearCart();
    return result;
  }
}
2. 购物车页面交互

entry/src/main/ets/pages/CartPage.ets

import { CartManagementUtil } from '../utils/CartManagementUtil';

@Entry
@Component
struct CartPage {
  @State cartList: Array<cart.CartItem> = [];

  build() {
    Column({ space: 16 }) {
      ListComponent({
        data: this.cartList,
        renderItem: (item: cart.CartItem, index: number) => {
          Row({ space: 16 }) {
            Image(item.avatarUrl)
              .width(80)
              .height(80)
              .objectFit(ImageFit.Cover)
              .borderRadius(8);
            Column({ space: 8 }) {
              Text(item.name)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
                .textColor('#000000');
              Text(item.description)
                .fontSize(14)
                .textColor('#666666')
                .maxLines(2)
                .textOverflow({ overflow: TextOverflow.Ellipsis });
              Text(`¥${item.price}`)
                .fontSize(16)
                .fontWeight(FontWeight.Bold)
                .textColor('#FF0000');
            }
              .layoutWeight(1);
            Row({ space: 8 }) {
              ButtonComponent({
                text: '-',
                onClick: async () => {
                  await this.modifyCartItemQuantity(item.cartItemId, item.quantity - 1);
                },
                disabled: item.quantity <= 1
              });
              Text(`${item.quantity}`).fontSize(14).textColor('#000000');
              ButtonComponent({
                text: '+',
                onClick: async () => {
                  await this.modifyCartItemQuantity(item.cartItemId, item.quantity + 1);
                },
                disabled: item.quantity >= 10
              });
            }
              .width('auto')
              .height('auto');
            ButtonComponent({
              text: '删除',
              onClick: async () => {
                await this.deleteCartItem(item.cartItemId);
              },
              disabled: false
            });
          }
            .width('100%')
            .height('auto')
            .padding(16)
            .backgroundColor('#FFFFFF')
            .borderRadius(8)
            .margin({ bottom: 8 });
        },
        onItemClick: (item: cart.CartItem, index: number) => {
          router.pushUrl({ url: '/pages/ProductDetailPage', params: { productId: item.productId } });
        }
      });
      ButtonComponent({
        text: '清空购物车',
        onClick: async () => {
          await this.clearCart();
        },
        disabled: this.cartList.length === 0
      });
    }
      .width('100%')
      .height('100%')
      .padding(16)
      .backgroundColor('#F5F5F5');
  }

  aboutToAppear() {
    CartManagementUtil.getInstance().init();
    this.getCartList();
  }

  async getCartList(): Promise<void> {
    this.cartList = await CartManagementUtil.getInstance().getCartList();
  }

  async modifyCartItemQuantity(cartItemId: number, quantity: number): Promise<void> {
    const result = await CartManagementUtil.getInstance().modifyCartItemQuantity(cartItemId, quantity);
    if (result.success) {
      this.getCartList();
    } else {
      promptAction.showToast({ message: '修改购物车商品数量失败' });
    }
  }

  async deleteCartItem(cartItemId: number): Promise<void> {
    const result = await CartManagementUtil.getInstance().deleteCartItem(cartItemId);
    if (result.success) {
      this.getCartList();
    } else {
      promptAction.showToast({ message: '删除购物车商品失败' });
    }
  }

  async clearCart(): Promise<void> {
    const result = await CartManagementUtil.getInstance().clearCart();
    if (result.success) {
      this.getCartList();
    } else {
      promptAction.showToast({ message: '清空购物车失败' });
    }
  }
}

五、部署与验证

配置完成后,需在 DevEco Studio 中编译 HAP 包并部署至真机测试。重点验证以下场景:

  • 用户注册与登录流程是否顺畅;
  • 商品列表加载速度与搜索准确性;
  • 购物车数量增减及删除操作的即时性;
  • 异常提示(如网络错误)是否友好。

完成上述步骤后,系统已具备完整的电商基础闭环能力,可在此基础上继续拓展订单与支付模块。

目录

  1. 鸿蒙电商购物车全栈实战:用户管理、商品列表与购物车实现
  2. 一、用户管理基础与架构
  3. 二、用户管理实战
  4. 1. 用户注册实现
  5. 2. 用户登录与信息维护
  6. 三、商品列表实战
  7. 1. 商品列表与搜索
  8. 2. 商品详情与加购
  9. 四、购物车管理实战
  10. 1. 购物车工具类封装
  11. 2. 购物车页面交互
  12. 五、部署与验证

更多推荐文章

查看全部
  • 基于 Python 与开源 AI 构建本地智能问答系统
  • JavaSE 核心知识点总结
  • mdev 与 udev:嵌入式及桌面 Linux 设备管理对比
  • 2024 年大模型时代下数据标注的变革趋势
  • C++ 多态详解:从概念到实现原理
  • C4.5 决策树算法原理与 C 语言实现详解
  • OpenClaw 接入飞书机器人配置教程
  • OpenClaw 深度解析:AI 代理的潜力、风险与真实定位
  • 半小时基于 OpenClaw 搭建 AI 量化系统:开源三件套实测
  • sherpa-onnx:将 Whisper、SenseVoice 等模型部署到手机的离线语音框架
  • 前端开发者必备的三个核心技能:AI 设计、工程实践与硬件效率
  • C++ 类与对象进阶特性与编译器优化实战
  • Supabase 全栈开发实战:从云端服务到本地部署
  • 奥迪 A6/A7 CarPlay 激活与 8511 地图安装指南
  • 基于ESP32-C3的RISC-V智能家居中控实战
  • C++ 内存管理解析:现代视角下的核心机制与实践
  • Android 动态加载技术:原理、场景与实现思路
  • Andrej Karpathy 解析人工智能未来发展策略
  • 大模型时代的机遇与挑战:技术赋能与个人成长
  • Spring Cloud 微服务远程调用:OpenFeign 实战

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online