HarmonyOS《柚兔学伴》项目实战25-我的页面、Web 嵌入与项目总结
2026/7/24 5:07:20 网站建设 项目流程

25. 我的页面、Web 嵌入与项目总结

本章导读

「我的」页面是应用的个人中心入口,承载用户信息、积分管理、系统设置等功能。本章将详解 MineView 的登录状态管理、WebPage 的网页嵌入、SettingPage 与 AboutPage 的设置体系,并对整个项目的架构设计与最佳实践进行全面总结。


25.1 MineView 个人中心

用户信息展示

MineView 展示头像、昵称和登录状态,未登录时点击头像触发登录:

// MineView.ets@Componentexportstruct MineView{@StateisLoggedIn:boolean=false;@StateuserInfo:string='未登录';@StateuserNickname:string='柚兔';@Stateavatar:Resource|string=$r('app.media.ic_avatar');aboutToAppear():void{this.updateLoginState()}build(){Column(){Row({space:10}){Image(this.avatar).width(48).clip(true).borderRadius(30).onClick(()=>{if(!this.isLoggedIn){this.login()}})Column({space:8}){Text(this.userInfo).fontSize(16).fontWeight(FontWeight.Bold)Text('书山有路勤为径').fontColor($r('app.color.color_sub_text')).fontSize(12)}.layoutWeight(1).alignItems(HorizontalAlign.Start)Image($r('app.media.ic_setting')).width(32).onClick(()=>{this.pageContext.openPage({routerName:'SettingPage',onReturn:async(data)=>{this.updateLoginState()}},true);})}.backgroundColor($r('app.color.color_card')).borderRadius(5).padding(12)}}}

登录流程

登录通过 BackupManager 华为账号服务实现:

login(){constbackupManager=BackupManager.getInstance();if(!BackupManagerService.getInstance().isBackupManagerInitialized()){promptAction.showToast({message:'等待初始化完成'});return;}this.isLoggedIn=UserInfoManager.isLoggedIn();if(this.isLoggedIn)return;try{backupManager.login();setTimeout(()=>{this.updateLoginState();},1000);}catch(error){console.error('登录失败:',error);}}

登录状态更新

privateupdateLoginState(){this.isLoggedIn=UserInfoManager.isLoggedIn();if(this.isLoggedIn){constuserInfoData=UserInfoManager.getUserInfo();this.userInfo=`${userInfoData?.nickName||'未登录'}`;this.avatar=userInfoData?.avatarUri||$r('app.media.ic_avatar')}else{this.userInfo='未登录';this.avatar=$r('app.media.ic_avatar')}}

UserInfoManager封装了华为账号的用户信息读取,isLoggedIn()判断登录状态,getUserInfo()获取昵称和头像 URI。

CardItem 列表导航

MineView 使用通用CardItem组件构建功能列表:

Column({space:12}){CardItem({name:'我的积分'}).onClick(()=>{this.pageContext.openPage({routerName:'ScorePage'},true);})CardItem({name:'反馈建议'}).onClick(()=>{this.pageContext.openPage({param:{title:'反馈建议',url:'https://ncn1rpfvd5vb.feishu.cn/share/base/form/shrcnwljf1ptBZVyKfmWH3eS6Ih',}asResultParams,routerName:'WebPage',},true);})}

通过ResultParams传递标题和 URL 给 WebPage,实现从原生到 Web 的无缝跳转。


25.2 WebPage 网页嵌入

核心实现

WebPage 使用 ArkUI 的 Web 组件嵌入网页,配合webview.WebviewController控制页面行为:

// WebPage.etsimport{webview}from'@kit.ArkWeb';@Componentstruct WebPage{controller:webview.WebviewController=newwebview.WebviewController();@Stateurl:string=''@Statetitle:string=''@StateisLoading:boolean=truebuild(){NavDestination(){Column(){TopBar({title:this.title,onBack:()=>{this.pageContext.popPage(true)}})Stack(){Web({src:this.url,controller:this.controller}).layoutWeight(1).onPageEnd(()=>{this.isLoading=false})LoadingProgress().width(40).height(40).visibility(this.isLoading?Visibility.Visible:Visibility.None)}.layoutWeight(1)}}.onReady((ctx:NavDestinationContext)=>{constparams=ctx.pathInfo.paramasResultParams;this.url=params.urlasstringthis.title=params.titleasstring})}}

ResultParams 接口

exportinterfaceResultParams{score?:numberfirstScore?:numbersecondScore?:numberthirdScore?:numberforthScore?:numberoddScore?:numberevenScore?:numbertype?:numbertitle?:stringurl?:string}

该接口同时服务多个页面(积分详情、Web 页面等),通过titleurl字段驱动 WebPage 的标题栏和网页地址。

加载状态处理

onPageEnd回调在网页加载完成时触发,关闭 LoadingProgress 指示器:

.onPageEnd(()=>{this.isLoading=false})

isLoading默认为 true,页面初始即显示加载动画,加载完成后切换为 Web 内容。


25.3 SettingPage 设置页

SettingPage 提供隐私政策入口与退出登录功能:

// SettingPage.ets@Componentstruct SettingPage{build(){NavDestination(){Column(){TopBar({title:'设置',onBack:()=>{this.pageContext.popPage(true)}})Column({space:12}){CardItem({name:'儿童隐私政策'}).onClick(()=>{this.pageContext.openPage({param:{title:'儿童隐私政策',url:'http://www.ai-youtoo.cn/partner_children_privacy.html',}asResultParams,routerName:'WebPage',},true);})CardItem({name:'关于我们'}).onClick(()=>{this.pageContext.openPage({routerName:'AboutPage'},true);})}.backgroundColor($r('app.color.color_card')).borderRadius(12).padding(12)Blank().layoutWeight(1)Button('退出登录',{type:ButtonType.Normal}).backgroundColor($r('app.color.app_alert')).onClick(async()=>{UserInfoManager.clearUserInfo()this.pageContext.popPage(true,newObject({index:0}))});}}}}

退出登录时调用UserInfoManager.clearUserInfo()清除本地用户数据,然后返回上一页。MineView 通过onReturn回调自动刷新登录状态。


25.4 AboutPage 关于页

AboutPage 展示应用品牌信息:

// AboutPage.ets@Componentstruct AboutPage{build(){NavDestination(){Column({space:10}){TopBar({title:'关于我们',onBack:()=>{this.pageContext.popPage(true)}})Column({space:10}){Image($r('app.media.startIcon')).width(60).height(60).margin({top:20})Text('柚兔学伴').fontSize(18).margin({top:10,bottom:40})Blank().layoutWeight(1)Text('柚兔(山东)网络科技有限责任公司').fontSize(12).fontColor($r('app.color.color_text')).margin({top:30})Text('鲁ICP备2024092126号-4A').fontSize(12).fontColor($r('app.color.color_text'))}}}}}

布局采用Blank().layoutWeight(1)将公司信息推至底部,营造居中对称的视觉感。


25.5 项目架构总览

九模块架构

StudyPartner/ ├── entry/ # 主入口模块(EntryAbility、HomePage) ├── common/ # 公共模块(工具类、管理器、通用组件) ├── feature/ │ ├── todo/ # 待办与诗词模块 │ ├── stroke/ # 笔画查询模块 │ └── my/ # 个人中心模块 ├── backup_air/ # 云备份与登录模块 ├── network/ # 网络请求模块 └── smartxplayer/ # 音频播放模块

模块化优势:

  • 功能边界清晰,团队可并行开发
  • 模块可独立编译测试,提升构建效率
  • 公共能力统一收敛到 common,避免代码重复

MVVM 模式

View (Component) ←→ ViewModel (Model类) ←→ Model (Database/Preferences)

以 StrokeView 为例:

  • View:StrokeView 组件,负责 UI 渲染与用户交互
  • ViewModel:StrokeModel 单例,管理笔画数据与 AI 对话状态
  • Model:CharacterService + 云端 API,提供汉字数据

25.6 最佳实践总结

通用组件抽取

项目抽取了高频使用的通用组件:

组件用途使用位置
TopBar顶部导航栏所有二级页面
CardItem列表行项MineView、SettingPage
IconText图标+文字功能入口TodoView
LoadingView全局加载态TodoView
CustomImageToggle自定义开关TodoView 任务完成

抽取原则:同一 UI 模式出现 3 次以上即抽取为通用组件。

数据库封装模式

所有 RDB 数据库遵循统一封装范式:

classXxxDatabase{privatestore:relationalStore.RdbStore|null=null;asyncinitialize(){/* getRdbStore + executeSql */}asyncaddXxx(){/* insert */}asyncgetXxxById(){/* query + equalTo */}asyncgetAllXxx(){/* query + orderByDesc */}asyncupdateXxx(){/* update + equalTo */}asyncdeleteXxx(){/* delete + equalTo */}asyncclose(){/* store.close */}privateresultSetToXxx(){/* ResultSet → 接口对象 */}}

TodoDatabase、GiftExchangeDatabase 均遵循此模式,新增数据实体只需替换表名和字段。

单例模式

需要全局共享状态的管理器使用单例:

BackupManager.getInstance()UserInfoManager(静态方法)RecordUtils.getInstance()BreakpointSystem HttpManager

控制器模式

组件间通信采用控制器解耦:

  • TimerComponentController:外部控制倒计时启动/暂停/重置
  • LottieController:控制 Lottie 动画播放/暂停/停止
  • webview.WebviewController:控制 Web 页面前进/后退/刷新

全局状态管理

// 写入AppStorage.setOrCreate('GlobalInfoModel',model)// 只读绑定@StorageProp('GlobalInfoModel')globalInfoModel:GlobalInfoModel=AppStorage.get('GlobalInfoModel')!

@StorageProp单向绑定,UI 只读不写;@StorageLink双向绑定,UI 可修改。


25.7 性能优化要点

LazyForEach 懒加载

长列表使用LazyForEach替代ForEach,按需加载列表项:

List(){LazyForEach(this.dataSource,(item)=>{ListItem(){/* ... */}})}

ForEach一次性创建所有节点,LazyForEach仅渲染可视区域,大幅减少内存占用。

图片缓存与资源管理

  • 图片资源使用$r()引用,系统自动管理缓存
  • Lottie 动画在aboutToDisappear中清理控制器
  • Canvas 上下文在页面销毁时置空

定时器清理

所有setInterval必须在aboutToDisappear中清除:

aboutToDisappear():void{if(this.internalId){clearInterval(this.internalId)}if(this.strokeManager!=null){this.strokeManager.stopAnimation();this.strokeManager.resetAnimation()}if(this.context){this.context.clearRect(0,0,100,100);this.context=null}}

25.8 发布准备

签名配置

Release 版本需要配置正式签名:

// build-profile.json5 { "signingConfigs": [{ "name": "release", "type": "HarmonyOS", "material": { "certpath": "certs/release.cer", "storePassword": "...", "keyAlias": "release", "keyPassword": "...", "profile": "certs/release.p7b", "signAlg": "SHA256withECDSA", "storeFile": "certs/release.p12" } }] }

版本管理

  • versionCode:递增整数,每次发布 +1
  • versionName:语义化版本号(如 1.0.0)

严格模式合规

ArkTS 严格模式下需注意:

  • 禁止使用any类型
  • 禁止运行时类型变更
  • 必须显式初始化类属性
  • 空安全:可选属性需用?.或非空断言!!

全系列总结

至此,「柚兔学伴」HarmonyOS 项目教程全 25 讲完结。我们从项目创建与基础导航开始,逐步覆盖了:

  • 基础架构:多模块工程、Navigation 导航、TabBar 布局
  • 数据持久化:Preferences 轻量存储、RDB 关系数据库
  • 核心功能:待办管理、诗词朗读、笔画查询、字帖生成、PDF 导出
  • 进阶能力:AI 智能体对话、Lottie 动画、Canvas 绘制、语音交互
  • 生态集成:华为账号登录、云存储、Web 嵌入、系统文件选择器
  • 工程实践:组件抽取、单例模式、控制器解耦、性能优化、发布流程

HarmonyOS 的 ArkUI 声明式开发范式为儿童教育应用提供了丰富而高效的能力支撑。希望本系列能帮助开发者在鸿蒙生态中快速构建高质量应用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询