
掌握状态监听和对象级响应提升 ArkUI 状态管理能力一、前言ArkUI 的状态管理体系中除了基础的 State/Prop/Link 和跨级通信的 Provide/Consume还有两个重要的装饰器Watch 和 ObjectLink。Watch监听状态变化执行回调函数ObjectLink监听对象的属性级变化避免不必要的重新渲染二、Watch - 状态监听2.1 基本用法Watch 用于监听 State 变量的变化变化时自动执行回调Componentstruct DistanceTracker{StateWatch(onDistanceChanged)distance:number0;StateWatch(onStatusChanged)status:stringidle;// Watch 回调每次 distance 变化时触发onDistanceChanged():void{console.log(距离更新:${this.distance}km);this.checkMilestone();}onStatusChanged():void{console.log(状态变更:${this.status});}checkMilestone():void{if(this.distance10this.distance10.01){console.log( 达到10公里里程碑);}}build(){Column(){Text(距离:${this.distance.toFixed(2)}km);Button(模拟前进).onClick((){this.distance0.5;// 触发 Watch 回调});Button(停止).onClick((){this.statuscompleted;// 触发 Watch 回调});}}}2.2 与 Link/Prop 配合Componentstruct ChildComponent{LinkWatch(onValueChange)sharedValue:number;onValueChange():void{console.log(子组件检测到值变化:${this.sharedValue});// 可以在此执行数据验证、副作用等}}2.3 Watch 与计算属性由于 ArkTS 不支持计算属性getter可以用 Watch 模拟Componentstruct RouteStats{StateWatch(calcDerivedData)distance:number0;StateWatch(calcDerivedData)duration:number0;Statepace:string0\00;// 派生状态StateavgSpeed:number0;// 派生状态calcDerivedData():void{// 当 distance 或 duration 变化时重新计算派生数据if(this.duration0this.distance0){this.pacethis.formatPace(this.duration,this.distance);this.avgSpeedthis.distance/(this.duration/3600);}}formatPace(seconds:number,km:number):string{constpacePerKmseconds/km;constminMath.floor(pacePerKm/60);constsecMath.floor(pacePerKm%60);return${min}${sec.toString().padStart(2,0)};}build(){Column(){Text(配速:${this.pace});Text(均速:${this.avgSpeed.toFixed(1)}km/h);}}}三、ObjectLink - 对象属性级监听3.1 解决的问题默认情况下State 监听的是对象引用变化而不是属性变化// ❌ 以下方式不会触发 UI 更新Stateroute{name:香山,distance:5};this.route.distance10;// 属性修改UI 不更新// ✅ 需要重新赋值this.route{...this.route,distance:10};ObjectLink 解决了这个问题可以监听对象属性的变化。3.2 使用 ObjectLink// 定义类需要使用 Observed 装饰ObservedclassTrackRecord{name:string;distance:number0;duration:number0;points:Coordinate[][];constructor(name:string){this.namename;}}// 父组件Componentstruct TrackDetail{Staterecord:TrackRecordnewTrackRecord(晨间徒步);build(){Column(){// 传入 ObjectLinkTrackInfo({record:this.record});Button(更新距离).onClick((){// ObjectLink 可以监听到属性变化this.record.distance1;});}}}// 子组件 - 使用 ObjectLink 接收Componentstruct TrackInfo{ObjectLinkrecord:TrackRecord;build(){Column(){Text(名称:${this.record.name});Text(距离:${this.record.distance.toFixed(1)}km);Text(用时:${this.record.duration}s);}}}3.3 Observed 装饰器使用 ObjectLink 前类必须用Observed装饰ObservedclassCoordinate{latitude:number0;longitude:number0;altitude:number0;}ObservedclassTrackPoint{coord:CoordinatenewCoordinate();heartRate:number0;timestamp:number0;}四、实战徒步迹实时轨迹追踪结合 ObjectLink 和 Watch实现轨迹追踪的实时更新ObservedclassTrackSession{name:string;startTime:number0;distance:number0;duration:number0;calories:number0;points:Coordinate[][];}Componentstruct TrackingController{ObjectLinksession:TrackSession;StatetimerId:number-1;start():void{this.session.startTimeDate.now();this.timerIdsetInterval((){this.session.duration;this.session.distance0.005;// 模拟轨迹点letpointnewCoordinate();point.latitude39.908Math.random()*0.01;point.longitude116.397Math.random()*0.01;this.session.points.push(point);},1000);}stop():void{clearInterval(this.timerId);}build(){Column(){Button(开始追踪).onClick(()this.start());Button(停止).onClick(()this.stop());}}}Componentstruct TrackingDisplay{ObjectLinksession:TrackSession;build(){Column(){Text(距离:${session.distance.toFixed(2)}km);Text(时长:${session.duration}s);Text(点数:${session.points.length});}}}EntryComponentstruct TrackingPage{StatetrackSession:TrackSessionnewTrackSession();build(){Column(){Text(轨迹记录).fontSize(20).fontWeight(FontWeight.Bold);TrackingDisplay({session:this.trackSession});TrackingController({session:this.trackSession});}.width(100%).height(100%).padding(16);}}五、Watch 与 ObjectLink 对比特性WatchObjectLink用途监听变化执行副作用监听属性级变化更新 UI使用位置状态变量上子组件参数接收依赖搭配 State/Link/Prop搭配 Observed 类触发时机变量赋值时对象属性变化时典型场景数据持久化、日志记录表单、实时数据展示六、性能优化建议避免频繁 Watch 回调中的复杂计算ObjectLink 适用于大型对象小型对象用 Prop 即可合理使用 Observed 范围不要过度装饰// ✅ 好在 Watch 中做轻量操作Watch(saveState)onStateChange():void{AppStorage.set(lastDistance,this.distance);}// ❌ 不好在 Watch 中做耗时操作onStateChange():void{this.heavyComputation();// 避免this.syncToServer();// 避免}七、总结Watch 和 ObjectLink 是 ArkUI 状态管理的高级特性。Watch 让你在状态变化时执行自定义逻辑ObjectLink 让你以更自然的方式修改对象属性。合理运用这些工具可以构建出响应迅速、代码优雅的鸿蒙应用。第一阶段1-10篇到此结束下一阶段我们将进入徒步迹核心页面的实战开发。下一篇预告鸿蒙原生开发手记徒步迹 - 应用生命周期与AbilityStage