HarmonyOS7 对象监听任务页实战:@Observed 与 @ObjectLink 不只是会用,还要用得顺手
文章目录先看两个被观察的对象addScore() 比构造函数更值得看ObjectLink 适合拆子组件页面结构怎么看完整代码写在最后Observed和ObjectLink很适合讲“对象级响应式”但只讲概念会有点飘。这个案例把它放到用户资料和每日任务里就好理解多了用户积分变了资料卡要刷新任务完成了任务行也要刷新。这类页面如果只靠普通对象很容易出现“数据确实改了但 UI 没动”的情况。HarmonyOS7 里做对象监听关键就是把对象本身纳入响应式体系。先看两个被观察的对象代码里有两个Observed类UserProfile和Task。前者保存用户名、年龄、等级、头像和积分后者保存任务 id、标题、完成状态和奖励积分。它们不是随便写的普通类。加上Observed后子组件可以通过ObjectLink观察对象属性变化。这样父组件传给子组件的不是一份死数据而是可以继续响应更新的对象。addScore()比构造函数更值得看用户完成任务后积分会增加积分达到等级阈值时还会升级。这个逻辑放在UserProfile.addScore()里比散落在按钮点击事件中清楚很多。addScore(pts:number){this.scoreptsif(this.scorethis.level*100){this.levelthis.scorethis.score-(this.level-1)*100}}这段代码说明了一个很实用的写法对象自己的业务规则尽量放回对象内部。页面只负责触发动作不要把升级规则、积分计算、UI 刷新混在一个点击事件里。ObjectLink适合拆子组件像用户卡片、任务行这种组件如果每个字段都用Prop传参数会越来越多而且子组件无法自然感知对象内部变化。ObjectLink更适合这种“整对象传入局部字段更新”的场景。不过它也不是万能的。只有对象被Observed标记ObjectLink才有意义如果对象结构经常临时加字段ArkTS 的静态类型也不会喜欢这种写法。页面结构怎么看ObservedProfilePage里维护了userProfile和taskList。用户资料卡关注积分和等级每日任务列表关注完成状态。读代码时可以先看两个类再看子组件如何接收对象最后看完成任务时怎么更新积分。如果你做的是用户中心、任务系统、订单卡片这类页面这种写法比一堆零散State更容易维护。完整代码下面是完整代码。入口组件名是ObservedProfilePage适合拿来练习 HarmonyOS7 中对象状态监听和子组件刷新。// Observed 与 ObjectLink 对象监听ObservedclassUserProfile{name:stringage:numberlevel:numberavatar:stringscore:numberconstructor(name:string,age:number,level:number,avatar:string,score:number){this.namenamethis.ageagethis.levellevelthis.avataravatarthis.scorescore}addScore(pts:number){this.scoreptsif(this.scorethis.level*100){this.levelthis.scorethis.score-(this.level-1)*100}}}ObservedclassTask{id:numbertitle:stringdone:booleanpoints:numberconstructor(id:number,title:string,done:boolean,points:number){this.ididthis.titletitlethis.donedonethis.pointspoints}}// 子组件用户卡片ObjectLink 监听 UserProfileComponentstruct UserCard{ObjectLinkuser:UserProfilebuild(){Column({space:10}){Row({space:12}){Text(this.user.avatar).fontSize(36).width(60).height(60).textAlign(TextAlign.Center).backgroundColor(#EFF6FF).borderRadius(30)Column({space:4}){Text(this.user.name).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#111827)Row({space:8}){Text(Lv.${this.user.level}).fontSize(12).fontColor(Color.White).backgroundColor(#2563EB).padding({left:8,right:8,top:2,bottom:2}).borderRadius(10)Text(年龄${this.user.age}).fontSize(12).fontColor(#6B7280)}}.alignItems(HorizontalAlign.Start).layoutWeight(1)Column({space:2}){Text(this.user.score.toString()).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#D97706)Text(积分).fontSize(11).fontColor(#9CA3AF)}.alignItems(HorizontalAlign.Center)}.width(100%).alignItems(VerticalAlign.Center)// 经验进度条Column({space:4}){Row(){Text(经验值).fontSize(12).fontColor(#6B7280).layoutWeight(1)Text(${this.user.score}/${this.user.level*100}).fontSize(12).fontColor(#2563EB)}Progress({value:this.user.score,total:this.user.level*100,type:ProgressType.Linear}).color(#2563EB).backgroundColor(#E5E7EB).style({strokeWidth:8}).width(100%)}}.width(100%).padding(16).backgroundColor(Color.White).borderRadius(12).shadow({radius:8,color:rgba(0,0,0,0.06),offsetY:2})}}// 子组件任务行ObjectLink 监听 TaskComponentstruct TaskRow{ObjectLinktask:TaskonComplete:(pts:number)void(){}build(){Row({space:12}){Text(this.task.done?✅:⬜).fontSize(22).onClick((){if(!this.task.done){this.task.donetruethis.onComplete(this.task.points)}})Column({space:3}){Text(this.task.title).fontSize(14).fontColor(this.task.done?#9CA3AF:#111827).decoration({type:this.task.done?TextDecorationType.LineThrough:TextDecorationType.None})Text(${this.task.points}积分).fontSize(12).fontColor(this.task.done?#9CA3AF:#D97706)}.alignItems(HorizontalAlign.Start).layoutWeight(1)if(!this.task.done){Text(去完成).fontSize(12).fontColor(#2563EB).backgroundColor(#EFF6FF).padding({left:10,right:10,top:4,bottom:4}).borderRadius(12).onClick((){this.task.donetruethis.onComplete(this.task.points)})}else{Text(已完成).fontSize(12).fontColor(#059669).backgroundColor(#D1FAE5).padding({left:10,right:10,top:4,bottom:4}).borderRadius(12)}}.width(100%).padding({left:16,right:16,top:12,bottom:12}).backgroundColor(this.task.done?#FAFAFA:Color.White).borderRadius(10).alignItems(VerticalAlign.Center)}}EntryComponentstruct ObservedProfilePage{StateuserProfile:UserProfilenewUserProfile(张三,25,3,‍,65)StatetaskList:Task[][newTask(1,完成每日签到,false,10),newTask(2,阅读一篇技术文章,false,20),newTask(3,完成一个练习项目,false,50),newTask(4,参与社区问答,false,30),newTask(5,分享学习心得,false,40),]build(){Column({space:0}){// 标题Text(Observed ObjectLink).fontSize(18).fontWeight(FontWeight.Bold).fontColor(#111827).width(100%).padding({left:20,right:20,top:20,bottom:4})Text(监听对象内部属性变化实现嵌套数据驱动视图).fontSize(13).fontColor(#6B7280).width(100%).padding({left:20,right:20,bottom:12})// 说明Row(){Text().fontSize(14).margin({right:6})Text(Observed 类 ObjectLink 子组件对象属性变化时触发子组件重渲染).fontSize(12).fontColor(#1E40AF).layoutWeight(1)}.width(100%).padding({left:16,right:16,top:8,bottom:8}).backgroundColor(#DBEAFE).margin({bottom:12}).alignItems(VerticalAlign.Top)Scroll(){Column({space:12}){// 用户卡片UserCard({user:this.userProfile}).margin({left:20,right:20})// 操作按钮Row({space:10}){Button(10 积分).fontSize(12).fontColor(#D97706).backgroundColor(#FEF3C7).borderRadius(16).padding({left:14,right:14,top:8,bottom:8}).onClick((){this.userProfile.addScore(10)})Button(50 积分).fontSize(12).fontColor(#059669).backgroundColor(#D1FAE5).borderRadius(16).padding({left:14,right:14,top:8,bottom:8}).onClick((){this.userProfile.addScore(50)})Button(年龄1).fontSize(12).fontColor(#7C3AED).backgroundColor(#F5F3FF).borderRadius(16).padding({left:14,right:14,top:8,bottom:8}).onClick((){this.userProfile.age})}.padding({left:20,right:20})// 任务列表标题Text(每日任务完成任务获得积分).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#374151).padding({left:20})Column({space:8}){ForEach(this.taskList,(task:Task){TaskRow({task:task,onComplete:(pts:number){this.userProfile.addScore(pts)}}).margin({left:20,right:20})},(task:Task)task.id.toString())}// 已完成统计Row({space:12}){Text(✅).fontSize(20)Text(已完成${this.taskList.filter((t:Task)t.done).length}/${this.taskList.length}任务).fontSize(14).fontColor(#374151).layoutWeight(1)Text(${this.taskList.filter((t:Task)t.done).reduce((s:number,t:Task)st.points,0)}积分).fontSize(14).fontWeight(FontWeight.Bold).fontColor(#D97706)}.width(100%).padding({left:20,right:20,top:12,bottom:12}).backgroundColor(#FFFBEB).margin({bottom:24}).alignItems(VerticalAlign.Center)}}.layoutWeight(1)}.width(100%).height(100%).backgroundColor(#F9FAFB)}}写在最后这个例子不复杂但很适合反复看。很多 ArkUI 页面写不顺其实不是组件不会用而是状态、结构和反馈没有放在一起设计。

相关新闻

单片机实验2

单片机实验2

一、IIC总线协议1.简介定义:是一种广泛用于嵌入式系统的同步、串行、半双工通信协议,用于在同一块电路板上的集成电路之间进行通信。I2C总线:是一种物理通信架构,用于连接多个设备,实现设备之间的数据传输。I2C协议&am…

2026/10/14 0:02:59 阅读更多 →
C++23 <stacktrace>库实战:跨平台调试与异常处理新利器

C++23 <stacktrace>库实战:跨平台调试与异常处理新利器

1. 项目概述:为什么我们需要一个标准化的栈踪迹库?调试,大概是每个C开发者又爱又恨的环节。爱的是,当程序在你面前崩溃,而你通过蛛丝马迹最终定位到那个深藏不露的bug时,那种成就感无与伦比;恨的…

2026/10/13 1:15:45 阅读更多 →
Spring框架@RequestAttribute注解详解与应用实践

Spring框架@RequestAttribute注解详解与应用实践

1. RequestAttribute 注解深度解析在Spring框架中,RequestAttribute注解是一个相对小众但非常实用的注解。它主要用于从请求作用域(request scope)中获取预先存在的属性值。与大家更熟悉的RequestParam不同,RequestAttribute不是用来获取请求参数的&…

2026/10/13 1:59:22 阅读更多 →

最新新闻

小型超市仓库管理系统

小型超市仓库管理系统

小型超市仓库管理系统选题背景与意义 随着我国城镇化进程的不断推进以及居民消费水平的持续提升,小型超市作为连接城市社区与消费者的重要商业节点,在日常生活中的作用日益凸显。尤其是在一二线城市周边的居民区、城乡结合部及中小城镇,小型超…

2026/10/14 0:02:42 阅读更多 →
小区物业管理系统

小区物业管理系统

小区物业管理系统选题背景与意义 随着我国城镇化进程的不断加快,城市住宅小区的数量持续增长,居民对居住环境品质的要求日益提高。现代社区不仅承担着基本的居住功能,更逐渐演变为集生活、休闲、服务于一体的综合性空间。在此背景下&#xff…

2026/10/14 0:02:42 阅读更多 →
IBM Verify Identity Access 修复 22 个漏洞:两个 9.8 严重 RCE 无需认证

IBM Verify Identity Access 修复 22 个漏洞:两个 9.8 严重 RCE 无需认证

一次补丁,二十二道口子被同时缝上。真正让人睡不着的,是其中两道连“敲门”都省了:攻击者不必拥有账号,不必骗用户点链接,也不必在边界外反复试探,只要目标还跑着受影响的 IBM Verify Identity Access 或 I…

2026/10/14 0:02:42 阅读更多 →
Caffe LISTFILE.txt生成与校验实战指南

Caffe LISTFILE.txt生成与校验实战指南

1. 项目概述:为什么一张LISTFILE.txt能决定训练成败在C Caffe框架下做图像分类或目标检测,你有没有遇到过这样的情况:模型跑起来了,loss也在降,但准确率卡在60%不上不下,反复调参、换网络结构、增大数据量都…

2026/10/14 0:02:42 阅读更多 →
Exchange 管理中心突发故障:微软确认“内部服务器错误”,管理员一度集体打不开后台

Exchange 管理中心突发故障:微软确认“内部服务器错误”,管理员一度集体打不开后台

你正想给员工重置一个邮箱密码,点击熟悉的 Exchange 管理中心网址,屏幕上却弹出一行冷冰冰的“内部服务器错误”——门户直接把你挡在了门外。2026年10月中旬,一场编号为 EX1500900 的突发访问故障悄然袭来,不少负责 Microsoft 36…

2026/10/14 0:02:42 阅读更多 →
等保2.0落地指南:从定级备案到整改自查的完整路线图

等保2.0落地指南:从定级备案到整改自查的完整路线图

简介:一份面向企业网络安全负责人、系统集成商及安全厂家的等保2.0三级基本要求深度解读资料,重点对照等级保护1.0梳理技术要求变化,特别剖析了安全通信网络、安全区域边界、安全计算环境等新增架构,以及合规分数由60分提升至75分…

2026/10/14 0:01:41 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →