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

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

本文实现了鸿蒙电商项目的核心模块,涵盖用户注册登录、信息管理、商品展示搜索及购物车增删改查功能。通过分层架构设计,整合了单例模式工具类与 ArkUI 页面组件,完成了前后端交互逻辑的闭环验证,为后续订单支付模块奠定基础。

CodeArtist发布于 2026/3/27更新于 2026/9/2070 浏览
鸿蒙电商购物车实战:用户管理、商品列表与购物车功能实现

鸿蒙电商购物车全栈项目:核心模块实现

项目架构示意

本章节聚焦于鸿蒙电商项目的核心业务逻辑,涵盖用户管理、商品展示及购物车流程。我们将基于现有的项目架构,完成基础功能的闭环开发。

一、用户管理基础与架构

用户管理是应用的基础设施,主要包含注册、登录、信息维护及权限控制。在架构设计上,我们采用分层模式:

  • 服务层:处理业务逻辑;
  • 数据层:负责存储与管理;
  • 接口层:定义交互协议;
  • 展示层:负责界面渲染。

这种结构有助于解耦,方便后续扩展与维护。

二、用户管理实战

1. 用户注册实现

首先构建注册工具类,采用单例模式确保全局唯一性。

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;
  }
}

页面组件中调用上述工具类,并处理 UI 交互:

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. 用户登录与信息维护

登录逻辑类似,重点在于会话保持与错误处理。信息管理页则允许用户更新个人资料和修改密码。

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

@Entry
@Component
struct UserInformationPage {
  @State userInformation: user.UserInformation | null = null;
  @State name: string = '';
  @State avatarUrl: string = '';
  @State oldPassword: string = '';
  @State newPassword: string = '';

  build() {
    Column({ space: 16 }) {
      if (this.userInformation) {
        Text(`用户 ID:${this.userInformation.userId}`).fontSize(14).textColor('#666666');
      }
      InputComponent({
        placeholder: '请输入姓名',
        value: this.name,
        onChange: (value: string) => { this.name = value; },
        type: InputType.Normal
      });
      InputComponent({
        placeholder: '请输入头像 URL',
        value: this.avatarUrl,
        onChange: (value: string) => { this.avatarUrl = value; },
        type: InputType.Normal
      });
      ButtonComponent({
        text: '修改用户信息',
        onClick: async () => { await this.modifyUserInformation(); },
        disabled: !this.name || !this.avatarUrl
      });
      InputComponent({
        placeholder: '请输入旧密码',
        value: this.oldPassword,
        onChange: (value: string) => { this.oldPassword = value; },
        type: InputType.Password
      });
      InputComponent({
        placeholder: '请输入新密码',
        value: this.newPassword,
        onChange: (value: string) => { this.newPassword = value; },
        type: InputType.Password
      });
      ButtonComponent({
        text: '修改密码',
        onClick: async () => { await this.modifyPassword(); },
        disabled: !this.oldPassword || !this.newPassword
      });
    }.width('100%').height('100%').padding(16).backgroundColor('#F5F5F5');
  }

  aboutToAppear() {
    UserInformationManagementUtil.getInstance().init();
    this.getUserInformation();
  }

  async getUserInformation(): Promise<void> {
    this.userInformation = await UserInformationManagementUtil.getInstance().getUserInformation();
    this.name = this.userInformation?.name ?? '';
    this.avatarUrl = this.userInformation?.avatarUrl ?? '';
  }

  async modifyUserInformation(): Promise<void> {
    const result = await UserInformationManagementUtil.getInstance().modifyUserInformation({
      userId: this.userInformation?.userId ?? 0,
      name: this.name,
      avatarUrl: this.avatarUrl,
      email: this.userInformation?.email ?? ''
    });
    if (result.success) {
      promptAction.showToast({ message: '修改用户信息成功' });
      this.getUserInformation();
    } else {
      promptAction.showToast({ message: '修改用户信息失败' });
    }
  }

  async modifyPassword(): Promise<void> {
    const result = await UserInformationManagementUtil.getInstance().modifyPassword(this.oldPassword, this.newPassword);
    if (result.success) {
      promptAction.showToast({ message: '修改密码成功' });
      this.oldPassword = '';
      this.newPassword = '';
    } else {
      promptAction.showToast({ message: '修改密码失败' });
    }
  }
}

三、商品列表与详情

商品模块需要高效展示数据并提供搜索能力。列表页使用 ListComponent 进行滚动渲染,详情页则提供数量选择与加入购物车入口。

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

@Entry
@Component
struct ProductListPage {
  @State productList: Array<product.Product> = [];
  @State searchKeyword: string = '';

  build() {
    Column({ space: 16 }) {
      InputComponent({
        placeholder: '请输入搜索关键词',
        value: this.searchKeyword,
        onChange: (value: string) => { this.searchKeyword = value; },
        type: InputType.Normal
      });
      ButtonComponent({
        text: '搜索',
        onClick: async () => { await this.searchProduct(); },
        disabled: !this.searchKeyword
      });
      ListComponent({
        data: this.productList,
        renderItem: (item: product.Product, 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);
            ButtonComponent({
              text: '查看详情',
              onClick: () => {
                router.pushUrl({ url: '/pages/ProductDetailPage', params: { productId: item.productId } });
              },
              disabled: false
            });
          }.width('100%').height('auto').padding(16).backgroundColor('#FFFFFF').borderRadius(8).margin({ bottom: 8 });
        },
        onItemClick: (item: product.Product, index: number) => {
          router.pushUrl({ url: '/pages/ProductDetailPage', params: { productId: item.productId } });
        }
      });
    }.width('100%').height('100%').padding(16).backgroundColor('#F5F5F5');
  }

  aboutToAppear() {
    ProductListUtil.getInstance().init();
    this.getProductList();
  }

  async getProductList(): Promise<void> {
    this.productList = await ProductListUtil.getInstance().getProductList();
  }

  async searchProduct(): Promise<void> {
    this.productList = await ProductListUtil.getInstance().searchProduct(this.searchKeyword);
  }
}

四、购物车管理

购物车是电商的核心,需支持增删改查操作。这里通过工具类封装了所有状态变更逻辑,确保数据一致性。

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 中执行编译打包(Build HAP),将生成的包部署至真机或模拟器进行测试。重点验证以下场景:

  • 用户注册与登录流程是否顺畅;
  • 商品信息加载与搜索响应速度;
  • 购物车增减商品后的价格计算与状态同步。

至此,用户体系、商品浏览及购物车核心链路已打通,为后续的订单与支付模块奠定了坚实基础。

目录

  1. 鸿蒙电商购物车全栈项目:核心模块实现
  2. 一、用户管理基础与架构
  3. 二、用户管理实战
  4. 1. 用户注册实现
  5. 2. 用户登录与信息维护
  6. 三、商品列表与详情
  7. 四、购物车管理
  8. 五、部署与验证

更多推荐文章

查看全部
  • 基于 LLaMA-Factory 与 Stable Diffusion 的跨模态创作工作流
  • 西门子 S7-1200 PLC 与爱普生机器人 Modbus TCP 通讯配置
  • 基于 Rokid AR 眼镜的聚会游戏助手开发实战
  • 大模型在安防领域的实践应用
  • OpenHarmony WebRTC 编译与适配指南
  • FPGA中扇出数目是什么意思
  • Llama-Factory 大模型微调工具实战指南
  • 黑客圈子里是否真的存在大量闷声发大财的土豪?
  • YOLOv8n 机器人场景目标检测实战:环境搭建与数据筛选
  • 基于百度天气 API 与 Leaflet 的 WebGIS 天气预报系统实现
  • RAG 检索增强生成:概念、原理与实战
  • Python 3.11.14 安装指南及安全修复说明
  • WSL2 下 Webots 启动地址错误 10.255.255.254 的原因与修复
  • Java 8 新特性:Stream API 使用指南
  • Android Framework 框架层源码深度解析:启动流程与核心组件
  • Stable Diffusion 3.5 FP8 发布:显存降 40%,推理提速近半
  • C++ 入门:C 语言没有的基础知识总结
  • C++ 输入输出与缺省参数详解
  • AI 绘画工具崩溃排查与性能优化实战指南
  • Spring 整合 Shiro 使用 Redis 缓存会话时报错排查与解决

相关免费在线工具

  • 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