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

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

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

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

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

项目架构图

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

一、用户管理基础与架构

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

  • 用户服务层:处理核心业务逻辑;
  • 用户数据层:负责数据的持久化存储;
  • 用户接口层:定义对外交互标准;
  • 用户展示层:负责 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. 五、部署与验证

更多推荐文章

查看全部
  • C++ 类与对象基础详解(上)
  • GLM-CookBook:智谱 GLM 大模型 API 入门指南
  • Spring Cloud 与 AI 结合构建分布式智能推荐系统
  • 滑动窗口算法实战:串联所有单词的子串与最小覆盖子串
  • 双指针算法核心概念与 C++ 经典例题解析
  • STL 源码剖析:list 容器从迭代器到算法实现
  • Linux 环境下 C/C++ 编译流程与链接机制详解
  • GitHub Copilot Pro 学生免费认证与 VS Code 集成指南
  • 基于深度学习的无人机洪水灾害图像分割与水量估算
  • AI 时代产品经理成长指南与核心能力模型
  • 2025 年 DeepSeek 开启 AI 算法变革元年深度解析
  • C++11 新特性深度解析:可变参数模板与 Lambda 表达式
  • C++ STL 基础:迭代器、auto 与范围循环
  • Python 开源 AI 模型引入及测试全流程
  • 前端团队协作最佳实践与效率提升
  • 链表十大经典算法题详解与实现
  • AIGC 在现代教育技术中的应用与前景
  • Google 发布 Med-Gemini 医学大模型:多模态与长文本处理突破
  • Docker 与 Ollama 本地部署 DeepSeek 大模型实战
  • SpringBoot 校园志愿者管理系统

相关免费在线工具

  • 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