目录

一.引言

二.开发工具和框架

三. 项目介绍

四. 功能介绍

4.1. 登录功能

4.2.忘记密码功能

4.3. 注册功能

4.4. 首页页面

4.5. 精选页面

4.6. 我的页面

4.7. 商品排行榜页面

4.8.购物车功能

4.9.点击返回功能

五. 项目总结

附录主要代码


一.引言

      我在这篇文章中分享了我的鸿蒙移动应用开发课程的期末大作业——小易购物app。项目基于ArkUI声明式开发框架构建,聚焦电商场景UI界面实现,所有展示数据均存储于本地,未涉及真实网络数据交互。通过搭建轮播图、商品列表、底部导航等核心模块,我系统掌握了ArkUI组件组合、布局设计等关键技能,切实感受到其简洁语法与高效开发优势。在此分享这份实践成果,为初识ArkUI的开发者提供直观参考,也期待与大家交流优化思路,共同进步。

二.开发工具和框架

    1. 核心开发工具:DevEco Studio 全流程应用,覆盖项目创建、编码、编译、调试等环节,运用模拟器完成多设备适配测试,借助调试工具高效排障,提升开发连贯性。

     2. 基础架构构建:依托 HarmonyOS SDK 搭建项目底层,熟练调用系统 API 与能力库,完成设备适配、权限配置,确保项目符合鸿蒙规范,筑牢业务开发基础。

    3. UI 开发框架:基于 ArkUI 声明式特性实现多端适配,运用组件库与布局方案,快速搭建一致性强、交互流畅的 UI 界面,提升开发效率与视觉统一性。

     4. 业务支撑组件:灵活运用 Ability、分布式数据管理、事件总线等组件,实现页面管理、跨设备数据同步与组件通信,高效支撑复杂业务落地。

     5. 开发规范与效率优化:严格遵循鸿蒙开发规范,封装复用 ArkUI 组件,减少重复开发,提升代码复用性与迭代效率,夯实工具与框架综合应用能力。

项目框架:

三. 项目介绍

    小易购物APP功能布局清晰,覆盖购物全流程。登录注册简洁,多种验证方式助力快速安全登录。首页精选爆款、新品与限时优惠,多元品类直观呈现,方便高效发现好物。购物车支持一键收藏商品,下单便捷。排行榜按销量排序,为选购提供可靠参考。“我的”页面整合实用服务,购物地址可新增、编辑及设置默认;我的最爱板块可收藏商品并实时关注动态。各功能衔接流畅,打造一站式舒适购物体验。

四. 功能介绍

4.1. 登录功能

    登录页面上展示 Logo 与 “欢迎登录” 标题,用户可在指定输入框填写用户名和密码(密码隐藏输入,均限 6 位),输入内容实时日志记录。点击蓝色 “注册” 文字,可快速跳转对应的注册页面。底部胶囊型登录按钮点击有反馈,若输入为空,将弹出 3 秒提示;输入完整则跳转主页面,异常情况会捕获错误并日志提示。输入框样式统一,全屏适配,从输入到跳转流程清晰,为用户提供便捷稳定的登录操作体验。

输入图片说明 输入图片说明

4.2.忘记密码功能

     这是鸿蒙应用的“忘记密码”页面,专为账号密码找回设计,操作简洁且校验贴心。顶部白色导航栏左侧,是44×44像素的透明返回按钮,点击内置24×24像素图标即可返回上一页;中间“忘记密码”标题居中粗显,明确页面用途。下方输入区域提示“请输入您绑定的手机号”,输入框限定数字输入,搭配白色背景与灰色占位符,清晰易操作。底部90%宽度的蓝色“确认”按钮,点击后会校验手机号:非11位则提示“请输入有效的手机号”,验证通过则弹窗提示并在1.5秒后跳转首页。整体浅灰背景搭配规整布局,操作流程顺畅,保障密码找回便捷安全。

输入图片说明

4.3. 注册功能

      这是鸿蒙系统的用户注册页面,操作简单直观!页面顶部展示Logo与“用户注册”标题,用户需填写用户名及两次密码(均限6位,密码隐藏输入),输入内容实时日志记录。点击蓝色“去登录”可跳转登录页,底部蓝色胶囊注册按钮点击有反馈。若信息未填全,将提示“用户名或密码不能为空”;两次密码不一致则弹窗提醒,注册成功后1.5秒自动跳转登录页,全程操作流畅,校验贴心,为新用户提供便捷注册体验。

输入图片说明

4.4. 首页页面

      这是鸿蒙应用的底部导航主页面,操作便捷直观!页面底部设有“首页”“精选”“我的”三个功能入口,每个入口搭配专属图标与文字,清晰易辨。点击对应导航项,即可快速切换至Home、choice、Mine三个核心页面,切换动画流畅(时长400毫秒)。导航栏占满全屏宽度,高度适配舒适,图标与文字大小搭配协调,视觉体验佳。无需复杂操作,通过底部一键切换,就能轻松访问应用各核心功能模块,为用户提供高效便捷的页面导航体验。

4.4.1 图片轮播组件

这是鸿蒙应用的图片轮播组件,操作无额外交互更省心!内置5张图片,默认从首张开始,5秒自动切换,切换动画时长3秒,支持循环播放。轮播图占95%宽度、160高度,顶部留5vp边距,隐藏指示器,整体简洁流畅,适配直观展示图片需求。

输入图片说明 输入图片说明 输入图片说明 输入图片说明

输入图片说明

4.4.2 顶部导航组件

这是鸿蒙应用的顶部导航组件,操作直观便捷!包含“首页”“精选”“排行榜”“购物车”“我的”五个入口,均搭配图标与文字,均匀分布且占满全屏。点击对应选项,即可快速跳转至关联页面,布局清晰、交互流畅,轻松切换应用核心功能。

输入图片说明

4.4.3 首页展示图

输入图片说明

4.5. 精选页面

      这是鸿蒙应用的商品分类浏览页面,操作直观且功能丰富!顶部设有横向滚动的分类导航栏,包含电子产品、生活用品、服装、时蔬、特价商品五大类,选中项以橙红底色+白色文字高亮区分,未选中项为灰色底黑字,清晰易辨。点击对应分类,下方网格区域即刻切换展示该类商品,无需额外加载步骤。商品以双列网格布局呈现,每张卡片包含图片、名称、价格,名称超出两行自动省略,价格标红醒目。卡片带轻微阴影与圆角,点击可跳转至商品详情页。页面整体背景简洁,分类导航支持横向滑动,商品区域可纵向滚动,分类切换流畅,商品展示清晰,为用户提供便捷的分类筛选与商品浏览体验。

4.5.1 电子产品页面

     含手机、耳机等,科技含量高,兼具通讯、娱乐功能,更新迭代快,如无线蓝牙耳机、智能手表等,提升生活便捷性。

输入图片说明

4.5.2 生活用品页面

          涵盖厨具、收纳等实用好物,像料理锅、收纳箱,注重实用性与环保,助力提升居家生活品质。

输入图片说明

4.5.3 服装页面

         含T恤、连衣裙等,风格多样适配不同场景,兼顾时尚与舒适,春秋风衣、夏季短袖均为热门品类。

输入图片说明

4.5.4 时蔬页面

          以新鲜果蔬为主,如荔枝、草莓,强调天然健康,部分为有机品类,是日常饮食的重要组成部分

输入图片说明

4.5.5 特价商品页面

          含清仓、临期等商品,价格低廉,如旧款耳机、断码服饰,性价比突出,满足实惠消费需求。

输入图片说明

4.6. 我的页面

         这是鸿蒙应用的“我的”个人中心页面,布局清晰、操作便捷!页面顶部是“我的”标题导航栏,下方展示用户头像、昵称“张三”及绑定邮箱,信息直观明了。中间功能区包含“我的订单”“我的收藏”“收货地址”三个核心入口,均为通栏设计,点击分别跳转至购物车、收藏页、地址管理页,满足订单查询、收藏管理、地址维护需求。底部设有“退出登录”按钮,占据90%页面宽度,点击即可返回登录页。整体采用白色功能块搭配浅灰色背景,视觉清爽,各区域间距合理,操作逻辑简单易懂,从个人信息查看、功能入口使用到退出登录,全程流程顺畅,为用户提供便捷的个人中心管理体验。

4.6.1 个人信息功能

     位于导航栏下方,左侧展示圆形头像,右侧清晰呈现昵称“张三”及绑定邮箱“11111@qq.com”。信息排布紧凑有序,视觉层次分明,让用户能快速确认个人账号信息,直观且易读。

输入图片说明

4.6.2 我的订单页面

     采用通栏设计融入功能列表,视觉上简洁易识别。点击后直接跳转至购物车页面,打破功能与操作的割裂感,方便用户快速查询订单状态、商品明细及物流信息,为订单管理提供直观且高效的入口,满足日常购物后的订单追踪需求。

输入图片说明

4.6.3 我的收藏页面

        以统一的通栏样式呈现,与其他功能入口形成视觉呼应。点击即可进入专属收藏页,用户可集中查看曾标记的心仪商品,无需重新搜索,便于对比筛选或直接购买,有效留存用户兴趣偏好,提升购物决策效率。

输入图片说明

4.6.4 收货地址页面

          通栏布局保证操作区域充足,点击后跳转至地址管理页面。在此用户可添加新地址、编辑现有地址或设置默认地址,解决网购中地址填写繁琐的问题,确保下单时地址信息准确无误,为顺畅购物提供基础保障。

输入图片说明

4.6.5 退出登录功能

       独立设置在页面底部,采用辨识度高的按钮形态,与功能列表形成区分。点击后即刻跳转回登录页面,操作响应迅速,既满足用户切换账号的需求,又能通过返回登录页保障账号安全,避免信息泄露风险。

输入图片说明

输入图片说明

4.7. 商品排行榜页面

     这是鸿蒙应用的“购买TOP10”商品排行榜页面,功能明确且操作便捷。顶部为白色导航栏,左侧是44×44像素的透明背景按钮,内置24×24像素返回图标,点击即可返回上一页;中间“购买TOP10”标题居中,字体粗重醒目。主体是纵向滚动的商品列表,展示销量前10商品,1-3名排名文字为橙红色,4-10名为深灰色,区分清晰。每栏含排名、60×60像素商品图、名称、红底价格及灰色销量信息,点击任意商品栏可跳转至对应详情页。页面以浅灰为底,白色商品栏间隔排布,交互流畅,助力快速锁定热门好物。

输入图片说明 输入图片说明

4.8.购物车功能

      这是鸿蒙应用的“我的购物车”页面,操作便捷且功能实用。顶部白色导航栏左侧,是44×44像素的透明返回按钮,点击图标即可返回上一页;中间“我的购物车”标题居中醒目。页面主体展示两款商品,均为“图片+信息+数量控制”布局,商品图60×60像素清晰呈现,价格标红突出。每款商品右侧设有“-”“+”按钮,点击可调整数量(数量不低于1),实时联动总价计算。底部结算栏显示实时总价,右侧橙红色“结算”按钮点击后弹出“结算成功”提示。整体浅灰背景搭配白色商品栏,布局规整,从返回导航、数量调整到结算,全程操作流畅,满足购物车核心使用需求。

输入图片说明

4.9.点击返回功能

        点击返回功能是保障用户操作连贯性的核心交互入口,设计贴心且操作零门槛。其载体为导航栏侧的专属按钮,尺寸固定为44×44像素,采用全透明背景设计,仅内嵌24×24像素的返回图标,既清晰易识别,又不干扰界面整体视觉。用户无需精准定位,轻触按钮区域即可触发返回指令,快速回到上一界面,避免在当前操作流程中滞留。该功能为用户提供灵活的操作退路,与当前页面核心业务流程形成互补,让整体交互更灵活,大幅提升操作体验的流畅度。

1.点击首页的排行榜,进入排行榜页面

输入图片说明

2.点击返回箭头,退出排行榜页面进入上一个页面

输入图片说明

五. 项目总结

     一、账号管理核心功能:应用以“购物服务+账号管理”为核心,账号端构建完整安全体系,涵盖注册登录、密码找回等功能。密码找回页面通过手机号校验身份,输入框限定数字格式,系统自动核验11位号码有效性,避免无效操作;所有账号相关页面均设明确操作指引,大幅降低用户使用门槛。

       二、购物服务核心模块:购物端形成“浏览-筛选-决策-结算”闭环,包含五大品类商品分类浏览、销量TOP10排行、购物车管理等模块。分类筛选助力快速定位需求,销量排行通过1-3名橙红、4-10名深灰的色彩区分,直观呈现热门商品;购物车支持商品数量增减(最低1件)与实时总价计算,结算后即时反馈结果。

      三、设计与体验优势:项目设计极具统一性,所有页面采用“顶部导航+主体内容+功能按钮”布局,顶部左侧标配44×44像素透明返回按钮,内嵌24×24像素图标,保障操作连贯。视觉上白块配浅灰背景,关键信息用橙红或蓝色突出,交互响应迅速,提供直观高效的使用体验。

       在本次项目的过程中,我收获颇丰。技术层面,通过实操深化了对核心业务场景的理解,熟练运用相关工具解决了数据处理、流程优化中的实际问题,编程与逻辑思维能力得到显著提升。协作上,在跨部门沟通与团队分工中,学会了精准表达需求、高效对接资源,也懂得了换位思考与互补协作的重要性。面对项目推进中的突发问题,我逐渐养成了拆解难题、复盘总结的习惯,抗压能力与问题解决效率大幅提高。此外,对项目全流程的把控让我建立了更系统的工作思维,严谨细致的态度也在反复打磨中愈发坚定。这些经验将成为我后续工作的重要积淀,激励我持续精进、稳步前行。

附录主要代码

1.登录页面

import router from '@ohos.router'
import promptAction from '@ohos.promptAction';

@Entry
@Component
struct Login {
  @State message: string = '欢迎登录';
  @State user: string = '';
  @State password: string = ''

  build() {
    Row() {
      Column() {
        //Logo
        Image($r('app.media.Logo'))
          .width(100)
          .height(20)
          .margin({ bottom: '20' })

        //欢迎登录
        Text(this.message)
          .fontSize('30')
          .fontWeight(FontWeight.Bold)

        //用户名和密码
        TextInput({ placeholder: '请输入用户名' })
          .inputStyle()
          .onChange(data => {
            this.user = data;
            console.info('user:' + data)
          })

        TextInput({ placeholder: '请输入密码' })
          .type(InputType.Password)//输入类型
          .inputStyle()
          .onChange(data => {
            this.password = data;
            console.info('password:' + data)
          })

        // --- 修改点:文字提示行 ---
        Row(){


          // 移除了“其他登录方式”相关代码

          // 新增“注册”选项
          Text('忘记密码')
            .fontSize('18fp')
            .fontColor(Color.Blue)
            .onClick(() => {
              // // 这里可以添加跳转到注册页面的逻辑
              // promptAction.showToast({ message: '' });
              router.pushUrl({ url: 'view/number' });
            })
          Text('注册')
            .fontSize('18fp')
            .fontColor(Color.Blue)
            .onClick(() => {
              // // 这里可以添加跳转到注册页面的逻辑
              // promptAction.showToast({ message: '' });
              router.pushUrl({ url: 'pages/RegisterPage' });
            })
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceAround)

        //登录
        Button('登录',{type:ButtonType.Capsule,stateEffect:true})
          .width('90%')
          .margin('10')
          .onClick(()=>{
            //路由跳转
            if(this.user==''||this.password==''){
              promptAction.showToast({
                message:'用户名或密码不能为空',
                duration:3000,
                bottom:'60'
              })
            }else {
              router.pushUrl({
                url:'pages/MainPage'
              }).catch((error:Error)=>{
                console.error(`跳转失败: ${error.message}`);
              })
            }
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

//添加公共样式函数
//@Extend装饰器
//@Extend(组件名称)function 样式名称
@Extend(TextInput) function inputStyle(){
  .placeholderColor(0x00001)
  .maxLength(6)
  .padding('12')
  .margin('10')
}

2.注册页面

import router from '@ohos.router';
import promptAction from '@ohos.promptAction';

@Entry
@Component
struct RegisterPage {
  @State message: string = '用户注册';
  @State username: string = '';
  @State password: string = '';
  @State confirmPassword: string = '';

  build() {
    Row() {
      Column() {
        //Logo
        Image($r('app.media.Logo'))
          .width(100)
          .height(20)
          .margin({ bottom: '20' })

        //标题
        Text(this.message)
          .fontSize('30')
          .fontWeight(FontWeight.Bold)
          .margin({ bottom: '20' })

        //用户名和密码输入框
        TextInput({ placeholder: '请输入用户名' })
          .inputStyle()
          .onChange(data => {
            this.username = data;
            console.info('username:' + data);
          })

        TextInput({ placeholder: '请输入密码' })
          .type(InputType.Password) // 输入类型为密码
          .inputStyle()
          .onChange(data => {
            this.password = data;
            console.info('password:' + data);
          })

        TextInput({ placeholder: '请确认密码' })
          .type(InputType.Password) // 输入类型为密码
          .inputStyle()
          .onChange(data => {
            this.confirmPassword = data;
            console.info('confirmPassword:' + data);
          })

        // 文字提示
        Row() {
          Text('已有账号?')
            .fontSize('18fp')
            .fontColor('#666666')
          Text('去登录')
            .fontSize('18fp')
            .fontColor(Color.Blue)
            .onClick(() => {
              router.pushUrl({ url: 'pages/LoginPage' });
            })
        }
        .width('100%')
        .justifyContent(FlexAlign.Center)
        .margin({ top: '10' })

        // 注册按钮
        Button('注册', { type: ButtonType.Capsule, stateEffect: true })
          .width('90%')
          .margin('10')
          .backgroundColor(Color.Blue) // 改为蓝色
          .fontColor('#ffffff')
          .onClick(() => {
            // 路由跳转前的简单校验
            if (this.username === '' || this.password === '' || this.confirmPassword === '') {
              promptAction.showToast({
                message: '用户名或密码不能为空',
                duration: 3000,
                bottom: '60'
              });
            } else if (this.password !== this.confirmPassword) {
              promptAction.showToast({
                message: '两次输入的密码不一致',
                duration: 3000,
                bottom: '60'
              });
            } else {
              // 模拟注册成功,跳转到登录页
              promptAction.showToast({ message: '注册成功' });
              setTimeout(() => {
                router.pushUrl({ url: 'pages/LoginPage' });
              }, 1500);
            }
          })

      }
      .width('100%')
      .padding('20')
    }
    .height('100%')
    .backgroundColor('#f5f5f5')
  }
}

// 添加公共样式函数
// @Extend装饰器
@Extend(TextInput) function inputStyle() {
  .placeholderColor(0x000002)
  .maxLength(6)
  .padding('12')
  .margin('10')
}

3.首页

import router from '@ohos.router'
import Home from '../view/HomePage'
import choice from '../view/choicePage'
import Mine from '../view/MinePage'

@Entry
@Component
struct Main {
  @State message: string = '首页';
  private controller:TabsController=new TabsController();
  @Builder TabBuilder1(){
    Column(){
      Image($r('app.media.home2'))
        .width(25)
        .height(25)
      Text('首页')
        .fontSize(10)
        .fontWeight(500)
    }
    .width('100%')
  }
  @Builder TabBuilder2(){
    Column(){
      Image($r('app.media.choice3'))
        .width(25)
        .height(25)
      Text('精选')
        .fontSize(10)
        .fontWeight(500)
    }
    .width('100%')
  }
  @Builder TabBuilder3(){
    Column(){
      Image($r('app.media.mine2'))
        .width(25)
        .height(25)
      Text('我的')
        .fontSize(10)
        .fontWeight(500)
    }
    .width('100%')
  }

  build() {
    Row(){
      Tabs({barPosition:BarPosition.End}){

        TabContent(){
          Home()

        }.tabBar(this.TabBuilder1())
        TabContent(){
          choice()

        }.tabBar(this.TabBuilder2())
        TabContent(){
          Mine()

        }.tabBar(this.TabBuilder3())
      }
      .vertical(false)//首页的位置
      .barWidth('100%')
      .barHeight('37')
      .animationDuration(400)
    }
    .height('100%')

  }
}

4.精选页面

import router from '@ohos.router';

@Entry
@Component
export default struct Choice {
  // 使用一个状态变量来记录当前选中的分类索引
  @State selectedTabIndex: number = 0;

  build() {
    Column() {
      // --- 1. 顶部手动写的分类导航栏 ---
      Scroll() {
        Row() {
          // 分类1:电子产品
          Text('电子产品')
            .fontSize(16)
            .fontColor(this.selectedTabIndex === 0 ? '#ffffff' : '#333333')
            .backgroundColor(this.selectedTabIndex === 0 ? '#ff4400' : '#f1f1f1')
            .padding({ left: 15, right: 15, top: 8, bottom: 8 })
            .borderRadius(20)
            .margin({ right: 10 })
            .onClick(() => {
              this.selectedTabIndex = 0;
            })

          // 分类2:生活用品
          Text('生活用品')
            .fontSize(16)
            .fontColor(this.selectedTabIndex === 1 ? '#ffffff' : '#333333')
            .backgroundColor(this.selectedTabIndex === 1 ? '#ff4400' : '#f1f1f1')
            .padding({ left: 15, right: 15, top: 8, bottom: 8 })
            .borderRadius(20)
            .margin({ right: 10 })
            .onClick(() => {
              this.selectedTabIndex = 1;
            })

          // 分类3:服装
          Text('服装')
            .fontSize(16)
            .fontColor(this.selectedTabIndex === 2 ? '#ffffff' : '#333333')
            .backgroundColor(this.selectedTabIndex === 2 ? '#ff4400' : '#f1f1f1')
            .padding({ left: 15, right: 15, top: 8, bottom: 8 })
            .borderRadius(20)
            .margin({ right: 10 })
            .onClick(() => {
              this.selectedTabIndex = 2;
            })

          // 分类4:时蔬
          Text('时蔬')
            .fontSize(16)
            .fontColor(this.selectedTabIndex === 3 ? '#ffffff' : '#333333')
            .backgroundColor(this.selectedTabIndex === 3 ? '#ff4400' : '#f1f1f1')
            .padding({ left: 15, right: 15, top: 8, bottom: 8 })
            .borderRadius(20)
            .margin({ right: 10 })
            .onClick(() => {
              this.selectedTabIndex = 3;
            })

          // 分类5:特价商品
          Text('特价商品')
            .fontSize(16)
            .fontColor(this.selectedTabIndex === 4 ? '#ffffff' : '#333333')
            .backgroundColor(this.selectedTabIndex === 4 ? '#ff4400' : '#f1f1f1')
            .padding({ left: 15, right: 15, top: 8, bottom: 8 })
            .borderRadius(20)
            .margin({ right: 10 })
            .onClick(() => {
              this.selectedTabIndex = 4;
            })
        }
        .padding(10)
      }
      .scrollable(ScrollDirection.Horizontal)
      .width('100%')
      .backgroundColor('#ffffff')
      .shadow({ radius: 2, color: '#00000010', offsetY: 2 })

      // --- 2. 根据选中的索引,手动显示对应的商品网格 ---
      Scroll() {
        // 使用 if / else if 来判断显示哪个分类的商品
        if (this.selectedTabIndex === 0) {
          // --- 电子产品 (使用本地图片) ---
          Grid() {
            GridItem() { this.ProductCard('无线蓝牙耳机 超长续航', '¥79.9', $r('app.media.51'), 1) }
            GridItem() { this.ProductCard('智能手表 心率监测', '¥199.0', $r('app.media.52'), 2) }
            GridItem() { this.ProductCard('便携式充电宝 20000mAh', '¥69.9', $r('app.media.53'), 3) }
            GridItem() { this.ProductCard('超薄全面屏手机', '¥2999.0', $r('app.media.54'), 4) }
            GridItem() { this.ProductCard('高清投影仪 家用', '¥1299.0', $r('app.media.55'), 5) }
            GridItem() { this.ProductCard('机械键盘 青轴', '¥249.0', $r('app.media.56jpg'), 6) }
            GridItem() { this.ProductCard('平板电脑 二合一', '¥6799.0', $r('app.media.57'), 7) }
            GridItem() { this.ProductCard('智能音箱', '¥199.0', $r('app.media.58'), 8) }
          }
          .columnsTemplate('1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
          .padding(10)
          .width('100%')
        } else if (this.selectedTabIndex === 1) {
          // --- 生活用品 (使用本地图片) ---
          Grid() {
            GridItem() { this.ProductCard('超值特惠 家用抽纸10包', '¥19.9', $r('app.media.61jpg'), 9) }
            GridItem() { this.ProductCard('网红爆款 全自动雨伞', '¥39.9', $r('app.media.62'), 10) }
            GridItem() { this.ProductCard('家用多功能料理锅', '¥129.0', $r('app.media.63'), 11) }
            GridItem() { this.ProductCard('高效除螨仪', '¥669.0', $r('app.media.64'), 12) }
            GridItem() { this.ProductCard('香薰机 超声波', '¥79.0', $r('app.media.65'), 13) }
            GridItem() { this.ProductCard('真空保鲜盒套装', '¥59.0', $r('app.media.66'), 14) }
            GridItem() { this.ProductCard('电动牙刷', '¥129.0', $r('app.media.67'), 15) }
            GridItem() { this.ProductCard('收纳箱 大号', '¥49.0', $r('app.media.68'), 16) }
          }
          .columnsTemplate('1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
          .padding(10)
          .width('100%')
        } else if (this.selectedTabIndex === 2) {
          // --- 服装 (使用本地图片) ---
          Grid() {
            GridItem() { this.ProductCard('夏季短袖T恤 宽松百搭款', '¥74', $r('app.media.71jpg'), 17) }
            GridItem() { this.ProductCard('时尚牛仔裤 直筒修身', '¥59.9', $r('app.media.72jpg'), 18) }
            GridItem() { this.ProductCard('女士连衣裙 夏季新款', '¥89.0', $r('app.media.73'), 19) }
            GridItem() { this.ProductCard('舒适运动套装', '¥119.0', $r('app.media.77jpg'), 20) }
            GridItem() { this.ProductCard('春秋季薄款风衣', '¥199.0', $r('app.media.81'), 21) }
            GridItem() { this.ProductCard('男士休闲衬衫', '¥79.0', $r('app.media.76'), 22) }
            GridItem() { this.ProductCard('保暖内衣套装', '¥69.0', $r('app.media.74jpg'), 23) }
            GridItem() { this.ProductCard('潮流帆布鞋', '¥59.0', $r('app.media.78'), 24) }
          }
          .columnsTemplate('1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
          .padding(10)
          .width('100%')
        } else if (this.selectedTabIndex === 3) {
          // --- 时蔬 (使用本地图片) ---
          Grid() {
            GridItem() { this.ProductCard('新鲜水果 妃子笑荔枝500g', '¥19.9', $r('app.media.82'), 25) }
            GridItem() { this.ProductCard('有机蔬菜组合 5斤装', '¥35.0', $r('app.media.83jpg'), 26) }
            GridItem() { this.ProductCard('精品西红柿 2斤', '¥12.9', $r('app.media.84'), 27) }
            GridItem() { this.ProductCard('鲜嫩黄瓜花 3斤', '¥33.8', $r('app.media.91jpg'), 28) }
            GridItem() { this.ProductCard('进口香蕉 1把', '¥12.8', $r('app.media.92jpg'), 29) }
            GridItem() { this.ProductCard('时令草莓 500g', '¥39.9', $r('app.media.94'), 30) }
            GridItem() { this.ProductCard('山东大樱桃 2斤', '¥89.0', $r('app.media.95'), 31) }
            GridItem() { this.ProductCard('清脆甜梨 4斤', '¥25.0', $r('app.media.98'), 32) }
          }
          .columnsTemplate('1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
          .padding(10)
          .width('100%')
        } else if (this.selectedTabIndex === 4) {
          // --- 特价商品 (使用本地图片) ---
          Grid() {
            GridItem() { this.ProductCard('清仓特价 旧款耳机', '¥29.9', $r('app.media.101jpg'), 33) }
            GridItem() { this.ProductCard('临期食品 零食大礼包', '¥19.9', $r('app.media.102'), 34) }
            GridItem() { this.ProductCard('断码T恤 买一送一', '¥39.0', $r('app.media.103'), 35) }
            GridItem() { this.ProductCard('瑕疵品 杯子', '¥5.0', $r('app.media.105jpg'), 36) }
            GridItem() { this.ProductCard('库存尾货 蓝牙音箱', '¥49.0', $r('app.media.106jpg'), 37) }
            GridItem() { this.ProductCard('过季外套 特价', '¥89.0', $r('app.media.107'), 38) }
            GridItem() { this.ProductCard('试用装化妆品', '¥19.0', $r('app.media.109'), 39) }
            GridItem() { this.ProductCard('促销礼品 马克杯', '¥9.9', $r('app.media.110'), 40) }
          }
          .columnsTemplate('1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
          .padding(10)
          .width('100%')
        }
      }
      .flexGrow(1)
      .width('100%')

    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f9f9f9')
  }

  /**
   * 封装一个商品卡片组件,避免重复代码
   * @param name 商品名称
   * @param price 商品价格
   * @param imageUrl 商品图片链接/本地图片资源
   * @param id 商品ID
   */
  @Builder ProductCard(name: string, price: string, imageUrl: Resource | string, id: number) {
    Column() {
      Image(imageUrl)
        .width('100%')
        .height(150)
        .objectFit(ImageFit.Cover)
      Text(name)
        .fontSize(14)
        .margin(5)
        .flexGrow(1)
        .maxLines(2)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
      Text(price)
        .fontSize(16)
        .fontColor('#ff4400')
        .margin(5)
        .alignSelf(ItemAlign.Start)
    }
    .padding(5)
    .backgroundColor('#fff')
    .borderRadius(8)
    .shadow({ radius: 3, color: '#00000008', offsetY: 2 })
    .onClick(() => {
      router.pushUrl({ url: `pages/ProductDetail?id=${id}` });
    })
  }
}

5.个人中心页面

import router from '@ohos.router';

@Entry
@Component
export default struct Mine {
  build() {
    // 根容器:垂直排列所有内容
    Column() {
      // --- 顶部导航栏 (之前已添加) ---
      Row() {


        Text('我的')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .flexGrow(1)
          .textAlign(TextAlign.Center)
      }
      .width('100%')
      .backgroundColor('#ffffff')
      .padding({ top: 5 })

      // 2. 用户信息区域
      Row() {
        Image($r('app.media.1')) // 头像
          .width(50)
          .height(50)
          .borderRadius(25)

        Column() { // 文字信息
          Text('张三')
            .fontSize(16)
          Text('11111@qq.com')
            .fontSize(12)
            .fontColor('#666666')
        }

      }
      .padding(15)
      .backgroundColor('#ffffff')
      .width('100%')

      // 3. 功能列表
      Column() {
        // 我的订单 (之前已修改)
        Row() {
          Text('我的订单')
            .fontSize(14)
            .flexGrow(1)

        }
        .padding(15)
        .width('100%')
        .onClick(() => {
          router.pushUrl({ url: 'view/cart' }); // 跳转到购物车
        })

        // --- 主要修改点:我的收藏 ---
        Row() {
          Text('我的收藏')
            .fontSize(14)
            .flexGrow(1) // 让文字占据左侧空间

        }
        .padding(15)
        .width('100%')
        .onClick(() => {
          // 跳转到 "我的收藏" 页面
          router.pushUrl({ url: 'view/mylove' });
        })

        // --- 主要修改点:收货地址 ---
        Row() {
          Text('收货地址')
            .fontSize(14)
            .flexGrow(1) // 让文字占据左侧空间

        }
        .padding(15)
        .width('100%')
        .onClick(() => {
          // 跳转到 "我的地址" 页面
          router.pushUrl({ url: 'view/myaddress' });
        })
      }
      .backgroundColor('#ffffff')
      .margin({ top: 10 })
      .width('100%')

      // 弹性拉伸,将按钮推到底部


      // 4. 退出登录按钮
      Button('退出登录')
        .width('90%')
        .height(40)
        .backgroundColor('#e5e8ea')
        .fontColor('#000000')
        .margin({ bottom: 30 })
        .onClick(() => {
          router.pushUrl({ url: 'pages/LoginPage' });
        })
    }
    .backgroundColor('#f5f5f5')
    .width('100%')
    .height('100%')
  }
}

源代码下载链接https://gitee.com/liu-shuqi-1/liushuqi

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐