跳到主要内容鸿蒙电商购物车项目:用户管理、商品列表与购物车实现 | 极客日志TypeScript大前端
鸿蒙电商购物车项目:用户管理、商品列表与购物车实现
综述由AI生成鸿蒙电商购物车项目涉及用户管理、商品列表及购物车功能实现。文章详细阐述了用户注册登录、信息管理的设计与代码,商品列表展示、搜索及详情页逻辑,以及购物车商品的添加、数量修改和删除操作。采用分层架构,基于 ArkTS 语言调用 Ohos 系统 API,完成基础功能开发,优化用户体验与数据安全。
CloudNative14 浏览 鸿蒙电商购物车全栈项目——用户管理、商品列表、购物车
项目概述
本文介绍鸿蒙电商购物车全栈项目的核心功能实现,涵盖用户管理、商品列表及购物车模块的基础开发。
学习目标:
- 掌握用户管理的设计与实现;
- 实现用户注册、登录、用户信息管理;
- 理解商品列表的设计与实现;
- 实现商品列表、商品详情、商品搜索;
- 掌握购物车管理的设计与实现;
- 实现添加商品到购物车、修改购物车商品数量、删除购物车商品;
- 优化用户体验(响应速度、数据安全)。
学习重点:
- 鸿蒙 APP 用户管理的开发流程;
- 商品列表的设计与实现;
- 购物车管理的设计与实现。
一、用户管理基础
1.1 用户管理定义
用户管理主要包括以下方面:
- 用户注册:支持手机号、邮箱等方式注册;
- 用户登录:支持手机号、邮箱等方式登录;
- 用户信息管理:管理个人信息;
- 用户权限管理:管理用户权限。
1.2 用户管理架构
采用分层架构,由以下部分组成:
- 用户服务层:负责业务逻辑;
- 用户数据层:负责数据存储与管理;
- 用户接口层:负责接口设计与实现;
- 用户展示层:负责界面渲染与交互。
二、用户管理实战
2.1 实战目标
基于项目架构,实现以下功能:
- 用户注册:支持手机号、邮箱等方式注册;
- 用户登录:支持手机号、邮箱等方式登录;
- 用户信息管理:管理个人信息。
2.2 用户注册实现
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;
}
}
2. 用户注册应用
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.3 用户登录实现
1. 用户登录工具类
entry/src/main/ets/utils/UserLoginUtil.ets
import user from '@ohos.user';
// 用户登录工具类
export class UserLoginUtil {
private static instance: UserLoginUtil | null = null;
private userHelper: user.UserHelper | null = null;
static getInstance(): UserLoginUtil {
if (!UserLoginUtil.instance) {
UserLoginUtil.instance = new UserLoginUtil();
}
return UserLoginUtil.instance;
}
async init(): Promise<void> {
if (!this.userHelper) {
this.userHelper = user.createUserHelper();
}
}
async login(email: string, password: string): Promise<user.UserLoginResult> {
if (!this.userHelper) {
return null;
}
const result = await this.userHelper.login(email, password);
return result;
}
async forgetPassword(email: string): Promise<user.ForgetPasswordResult> {
if (!this.userHelper) {
return null;
}
const result = await this.userHelper.forgetPassword(email);
return result;
}
}
2. 用户登录应用
entry/src/main/ets/pages/LoginPage.ets
import { UserLoginUtil } from '../utils/UserLoginUtil';
@Entry
@Component
struct LoginPage {
@State email: string = '';
@State password: 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 });
ButtonComponent({ text: '登录', onClick: async () => { await this.login(); }, disabled: !this.email || !this.password });
Text('忘记密码').fontSize(14).textColor('#666666').onClick(() => { this.forgetPassword(); });
}.width('100%').height('100%').padding(16).backgroundColor('#F5F5F5');
}
aboutToAppear() {
UserLoginUtil.getInstance().init();
}
async login(): Promise<void> {
const result = await UserLoginUtil.getInstance().login(this.email, this.password);
if (result.success) {
promptAction.showToast({ message: '登录成功' });
router.pushUrl({ url: '/pages/HomePage' });
} else {
promptAction.showToast({ message: '登录失败' });
}
}
async forgetPassword(): Promise<void> {
const result = await UserLoginUtil.getInstance().forgetPassword(this.email);
if (result.success) {
promptAction.showToast({ message: '密码重置邮件已发送' });
} else {
promptAction.showToast({ message: '密码重置邮件发送失败' });
}
}
}
2.4 用户信息管理实现
1. 用户信息管理工具类
entry/src/main/ets/utils/UserInformationManagementUtil.ets
import user from '@ohos.user';
export class UserInformationManagementUtil {
private static instance: UserInformationManagementUtil | null = null;
private userHelper: user.UserHelper | null = null;
static getInstance(): UserInformationManagementUtil {
if (!UserInformationManagementUtil.instance) {
UserInformationManagementUtil.instance = new UserInformationManagementUtil();
}
return UserInformationManagementUtil.instance;
}
async init(): Promise<void> {
if (!this.userHelper) {
this.userHelper = user.createUserHelper();
}
}
async getUserInformation(): Promise<user.UserInformation> {
if (!this.userHelper) {
return null;
}
const result = await this.userHelper.getUserInformation();
return result;
}
async modifyUserInformation(information: user.UserInformation): Promise<user.ModifyUserInformationResult> {
if (!this.userHelper) {
return null;
}
const result = await this.userHelper.modifyUserInformation(information);
return result;
}
async modifyPassword(oldPassword: string, newPassword: string): Promise<user.ModifyPasswordResult> {
if (!this.userHelper) {
return null;
}
const result = await this.userHelper.modifyPassword(oldPassword, newPassword);
return result;
}
}
2. 用户信息管理应用
entry/src/main/ets/pages/UserInformationPage.ets
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: '修改密码失败' });
}
}
}
三、商品列表实战
3.1 实战目标
- 商品列表:显示商品列表;
- 商品详情:显示商品详情;
- 商品搜索:搜索商品。
3.2 商品列表实现
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;
}
}
2. 商品列表应用
entry/src/main/ets/pages/ProductListPage.ets
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);
}
}
3.3 商品详情实现
1. 商品详情工具类
entry/src/main/ets/utils/ProductDetailUtil.ets
import product from '@ohos.product';
export class ProductDetailUtil {
private static instance: ProductDetailUtil | null = null;
private productHelper: product.ProductHelper | null = null;
static getInstance(): ProductDetailUtil {
if (!ProductDetailUtil.instance) {
ProductDetailUtil.instance = new ProductDetailUtil();
}
return ProductDetailUtil.instance;
}
async init(): Promise<void> {
if (!this.productHelper) {
this.productHelper = product.createProductHelper();
}
}
async getProductDetail(productId: number): Promise<product.Product> {
if (!this.productHelper) {
return null;
}
const result = await this.productHelper.getProductDetail(productId);
return result;
}
async addToCart(productId: number, quantity: number): Promise<product.AddToCartResult> {
if (!this.productHelper) {
return null;
}
const result = await this.productHelper.addToCart(productId, quantity);
return result;
}
}
2. 商品详情应用
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: '添加到购物车失败' });
}
}
}
四、购物车管理实战
4.1 实战目标
- 购物车列表:显示购物车列表;
- 添加商品到购物车:添加商品到购物车;
- 修改购物车商品数量:修改购物车商品数量;
- 删除购物车商品:删除购物车商品。
4.2 购物车管理工具类
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;
}
}
4.3 购物车应用
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: '清空购物车失败' });
}
}
}
五、项目配置与部署
5.1 配置文件修改
在 entry/src/main/module.json5 中添加用户管理、商品列表、购物车相关配置。
5.2 项目部署
- 编译项目:在 DevEco Studio 中点击 Build → Build HAP。
- 部署到设备:将编译后的 HAP 文件部署到鸿蒙设备上。
- 测试功能:验证用户注册、登录、信息管理、商品列表、详情、搜索及购物车操作。
相关免费在线工具
- 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