HarmonyOS 角落里的知识 —— 状态管理

news2024/11/17 15:31:08

 一、前言

在探索 HarmonyOS 的过程中,我们发现了许多有趣且实用的功能和特性。有些总是在不经意间或者触类旁通的找到。或者是某些开发痛点。其中,状态管理是ArkUI开发非常核心的一个东西,我们进行了大量的使用和测试遇到了许多奇奇怪怪的问题。

该系列将着重分享、介绍HarmonyOS API11+的新版本特性或者奇奇怪怪的解决方案、BUG。(弃用API非必要不提及)

二、@State

这应该是用的最多的了,状态变量,将状态变量和UI的某个属性绑定,即可同步两者。

  1. 初始化行为

    组件初始化时,@State只能从外面传入一次,之后父组件值的修改并不会影响到组件内部的@State,所以它叫组件内状态~(当然你组件用if、else来更新当我没说)

 @Entry
 @Component
 export struct ExpComponent {
     @State title: string = "Title"
 ​
     build() {
         Column() {
             ExpChildComponent({
                 childTitle: this.title
             })
             Button(this.title)
                 .onClick(()=>{
                     this.title = "Click"
                 })
         }
     }
 }
 @Component
 export struct ExpChildComponent {
     @State childTitle: string = "????"
 ​
     build() {
         Text(this.childTitle)
     }
 }
  1. 就像这样,onClick触发后ExpChildComponent并不会发生改变了。

  2. 太多的@State

    1. 一开始我们会直接将状态变量直接声明在组件中,如:
 @Component
 export struct ExpComponent {
     @State title: string = ""
 ​
     build() {
         Text(this.title)
     }
 }

但是随着,一个页面开始变得复杂的时候,我们会面临一堆的Controller,xxState等等,看起来就很头疼。这时候利用@State能观察到Object.keys(自身)返回的所有属性的特性,我们可以抽出一个ExpUIState

 @Component
 export struct ExpComponent {
     @State uiState: ExpUIState = new ExpUIState()
 ​
     build() {
         Text(this.uiState.title)
     }
 }
 ​
 class ExpUIState {
     title: string = ""
 }
  1. 如此,还你一个优雅的组件。

  2. 数组

    @State能直接修饰数组:

 @State title: Model[] = [new Model(1), new Model(2)];

数组自身的赋值可以观察到。

 this.title = [new Model(2)];

数组项的赋值可以观察到。

 this.title[0] = new Model(2);

删除数组项可以观察到。

 this.title.pop();

新增数组项可以观察到。

 this.title.push(new Model(12));

数组项中属性的赋值观察不到。

this.title[0].value = 6;
  • 数组对象及其子项的赋值是可以被观察到的,所以“titles[0].value = 1 ”这种使用方法是没用滴。

    4.作用域的影响

  • 得益于闭包的特性(对于Java、Kotlin开发来说不存在的东西)箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是使用时所在的作用域指向的对象。

    @Component
    export struct ExpComponent {
        @State uiState: ExpUIState = new ExpUIState()
    
        build() {
            Column() {
                Text(this.uiState.title)
                Button("Click").onClick(()=>{
                    this.uiState.autoRefreshTitle()
                })
            }
        }
    }
    class ExpUIState {
        title: string = "??"
        autoRefreshTitle = () => {
            this.title = "AutoRefreshTitle"
        }
    }
    

    上述操作,触发onClick是不会更新UI的,如果想要触发更新需要用下面的例子:

@Component
export struct ExpComponent {
    @State uiState: ExpUIState = new ExpUIState()

    aboutToAppear(): void {
    }

    build() {
        Column() {
            Text(this.uiState.title)
            Button("Click").onClick(()=>{
                let fk = this.uiState
                this.uiState.autoRefreshTitle(fk)
            })
        }
    }
}
class ExpUIState {
    title: string = "??"
    autoRefreshTitle = (st:ExpUIState) => {
        st.title= "AutoRefreshTitle"
    }
}
  1. 反人类吧?阿弥陀佛。

  2. 嵌套对象

    @State修饰对象时,里面可能还有对象,或者数组.

class ExpUIState {
    childs: ExpChild[] = []
    firstChild: ExpChild = new ExpChild()
}
  1. 很可惜的是,由于@State装饰的变量,只能监听到对象本身的地址以及第一层属性的地址变化,也就是firstChild或者childs地址的变化,例如如下操作:uiState.firstChild.subTtile="",uiState.childs.push(new ExpChild())等是没法触发刷新的。

    解决办法就是不用@State

三、@Prop

  1. 初始化行为

    几乎和@State一致,但是@Prop变量允许在本地修改,但修改后的变化不会同步回父组件。当数据源更改时,@Prop装饰的变量都会更新,并且会覆盖本地所有更改。因此,数值的同步是父组件到子组件(所属组件),子组件数值的变化不会同步到父组件。

    相比起@State重点就是父组件修改后子组件会同步。苦恼@State没法修改的人,有福了~

  2. 套一堆的@Prop

    不要这么做。如果你的子组件使用@Prop、孙子组件也用@Prop,我其实推荐你使用@Provide(当然你硬要用也行)

  3. @Require

    使用@Prop有一个好处就是,可以使用@Require。变成一个必传的参数(福音啊)。@State是可以不传的。

@Require @Prop index: number 

Observed

坏消息:@Prop也没法观察嵌套对象~,因为父组件传入时,用的@State传入的。好消息:加一个@Observed就好了~

@Component
export struct ExpComponent {
    @State uiState: ExpUIState = new ExpUIState()

    aboutToAppear(): void {
    }

    build() {
        Column() {
            ExpChildComponent({
                child: this.uiState.firstChild
            })
            Button("Click").onClick(() => {
                this.uiState.firstChild.subTitle = "????"
            })
        }
    }
}

@Component
export struct ExpChildComponent {
    @Require @Prop child: ExpChild

    build() {
        Text(this.child.subTitle)
    }
}


@Observed
class ExpUIState {
    childs: ExpChild[] = []
    firstChild: ExpChild = new ExpChild()
}

@Observed
class ExpChild {
    subTitle: string = "啊"
}

在嵌套场景下,每一层都要用@Observed装饰,且每一层都要被@Prop接收。

四、@Link

  1. 初始化行为

    @Link装饰的变量与其父组件中的数据源共享相同的值

    PS:从API version 9开始,@Link子组件从父组件初始化@State的语法为Comp({ aLink: this.aState })。同样Comp({aLink: $aState})也支持(早该如此了)

  2. 给Dialog用

    如果你在某个Dialog中,想同步数据到组件,@Link是一个很好的选择:

 @CustomDialog
 struct CustomDialog01 {
   @Link inputValue: string;
   controller: CustomDialogController;
 ​
   build() {
     Column() {
       Text('Change text')
         .fontSize(20)
         .margin({ top: 10, bottom: 10 })
       TextInput({ placeholder: '', text: this.inputValue })
         .height(60)
         .width('90%')
         .onChange((value: string) => {
           this.inputValue = value;
         })
     }
   }
 }
 ​
 @Entry
 @Component
 struct DialogDemo01 {
   @State inputValue: string = 'click me';
   dialogController: CustomDialogController = new CustomDialogController({
     builder: CustomDialog01({
       inputValue: $inputValue
     })
   })
 ​
   build() {
     Column() {
       Button(this.inputValue)
         .onClick(() => {
           this.dialogController.open();
         })
         .backgroundColor(0x317aff)
     }
     .width('100%')
     .margin({ top: 5 })
   }
 }
  1. 当然,你也可以传个函数进去~

  2. @Link套娃

    就像@Prop一样,我很建议你使用@Provide@Consume

五、@Watch

@Watch应用于对状态变量的监听,这个装饰器可以说是非常直观的一个了,就是用来观察状态变量的。

  1. 不要在里面修改状态变量

 @State @Watch("onUiStateChange") uiState: ExpUIState = new ExpUIState()
 onUiStateChange(){
     this.uiState.firstChild = new ExpChild()
 }
  • 相信你看得出来,这是一个死循环吧?

  • 子组件事件传递到父组件

    可通过状态同步@Link@Provide@Consume进行父子组件间的状态通知,结合@Watch可以将状态变量的修改在组件间传递,实现类似的功能。

  • 粘性

    @Watch没有粘性,所以第一次初始化并不会触发@Watch!

  • 日志

    @Watch可以观察状态变量变化的特性,很适合来做Log日志不是吗~



最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

鸿蒙HarmonyOS Next全套学习资料←点击领取!(安全链接,放心点击

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

鸿蒙(HarmonyOS NEXT)最新学习路线

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

HarmonyOS Next 最新全套视频教程

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

大厂面试必问面试题

鸿蒙南向开发技术

鸿蒙APP开发必备

鸿蒙生态应用开发白皮书V2.0PDF



获取以上完整鸿蒙HarmonyOS学习资料,请点击→

总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1839140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AD层次原理图绘制

一、在原理图中添加端口 二、添加层次图 三、更新层次图 四、也可以先画层次图,再绘制原理图,这里就不做演示了

天地图 uniapp使用笔记

官网地址&#xff1a;天地图API 效果&#xff1a; <template><view><!-- 显示地图的DOM节点 --><view id"container" class"content"></view><!-- END --><!-- 数据显示 --><h3>城市名称(IP属地)&#x…

关于归一化能量与归一化功率(连续与离散+1)

前言&#xff1a; ① 周期信号 与 直流信号 都是功率信号 ②一个信号可以既不是能量信号也不是功率信号&#xff0c;但不可能既是能量信号又是功率信号 归一化能量 对于一个连续时间信号 ( x(t) )&#xff0c;归一化能量 ( E ) 的定义为&#xff1a; E lim ⁡ T → ∞ ∫ −…

某宝APP参数通过SDK把APP参数转URL参数链接方法

app里参数无法在电脑端或者在没有XX宝的手机里支付, 所以需要转成H5参数进行代付操作 出某xx宝 支付sdk转h5链接方式算法

苹果不会等到明年才对 Siri 进行改进|TodayAI

据彭博社报道&#xff0c;今年苹果&#xff08;APPLE&#xff09;将推出一个更令人满意的 Siri。 当 iOS 18 今年秋季推出时&#xff0c;Siri 的功能不仅仅是让你的 iPhone 边缘显示彩虹光环。虽然苹果智能功能要到 2025 年才会向非测试版用户推出&#xff0c;但据报道&#x…

工作人员能从轧钢测径仪上获取哪些有效信息?

轧钢测径仪安装在轧钢生产线中&#xff0c;无论是热轧还是冷轧&#xff0c;都不能阻挡测径仪的高速无损高精检测。它采用八轴测量系统&#xff0c;能全方位检测外径尺寸&#xff0c;并且配备了测控软件系统&#xff0c;为工作人员提供更加丰富的产线信息。 普通轧钢测径仪能获…

跨境电商必备?揭秘原生IP的作用

一、什么是原生IP&#xff1f; 原生IP&#xff08;Native IP&#xff09;是指由互联网服务提供商&#xff08;ISP&#xff09;或服务器提供商直接分配给用户的IP地址&#xff0c;这种IP地址直接与用户设备或网络相连&#xff0c;也就是指这个IP的注册地址和服务器机房所在的国…

自养号补单:Shopee,Lazada等东南亚电商卖家销量提升的必备技能

在东南亚电商跨境平台中、lazada、shopee是东南亚地区最大的在线购物网站&#xff0c;其目标主要是印地&#xff0c;马来&#xff0c;台湾&#xff0c;菲律宾&#xff0c;新加坡&#xff0c;泰国和越南等用户。而自养号补单作为一种有效的推广手段&#xff0c;正逐渐被越来越多…

安防监控视频平台LntonAIServer视频智能分析平台烟火检测

LntonAIServer烟火检测技术是一种先进的技术&#xff0c;它结合了人工智能的强大能力&#xff0c;专门用于识别和检测烟雾或火焰的存在。这种技术在现代社会的许多领域中都发挥着至关重要的作用&#xff0c;尤其是在安全监控和火警预警系统等关键领域&#xff0c;它的应用更是不…

【PL理论】(33) 类型系统:推导树证明 φ ⊢ e∶t | 继续定义关系:γ ⊢ e∶t

&#x1f4ac; 写在前面&#xff1a;本章我们将讲解推导树证明&#xff0c;推导树实际上就是推理规则的应用。只要学会如何选择并应用适当的推理规则&#xff0c;证明就不是难事了。 目录 0x00 推导树证明 &#x1d753; ⊢ &#x1d486; ∶ &#x1d495; 0x01 继续定义关…

瑞数信息入选IDC《中国WAAP厂商技术能力评估,2024》

5星满分&#xff1a;WAF、Bot流量管理、行业应用等评估维度 日前&#xff0c;全球领先的IT市场研究和咨询公司IDC发布《中国WAAP厂商技术能力评估&#xff0c;2024》。报告聚焦WAAP能力&#xff0c;通过对中国市场中主要WAAP产品提供商的技术评估以及对大量最终用户的客观访谈…

深入了解 Android 中的 ViewStub

在 Android 开发中&#xff0c;性能优化一直是一个重要的话题。ViewStub 作为一种轻量级视图容器&#xff0c;可以帮助我们在合适的时机延迟加载视图&#xff0c;从而优化应用性能。本文将详细介绍 ViewStub 的概念、使用方法以及在实际开发中的应用场景。 什么是 ViewStub&am…

rollup学习笔记

一直使用的webpack,最近突然想了解下rollup,就花点时间学习下. 一,什么是rollup? rollup 是一个 JavaScript 模块打包器&#xff0c;可以将小块代码编译成大块复杂的代码,比如我们的es6模块化代码,它就可以进行tree shaking,将无用代码进行清除,打包出精简可运行的代码包. 业…

uniapp 微信小程序自定义分享图片

场景&#xff1a;微信小程序用户&#xff0c;点击小程序里商品的分享按钮时&#xff0c;想要不同的商品展示不用的分享内容&#xff0c;比如分享图片上展示商品的图片、价格等信息。分享的UI图如下&#xff1a; 实现方法&#xff1a; 1. 分享按钮&#xff1a;<button open-…

朋友圈新功能:实现定时发圈,自动跟圈

1.多号同时发圈 可以选择多个号同时发圈&#xff0c;提高工作效率。 2.定时发布 可以一次性设置完很多天的朋友圈&#xff0c;选好发送时间就可以解放双手。 3.一键转发 点击转发&#xff0c;可直接跳转到编辑页面。无需复制粘贴。 4.自动转发&#xff08;跟圈&#xff09; …

ATFX汇市:英国5月核心CPI年率下降0.4百分点,GBPUSD不跌反涨

ATFX汇市&#xff1a;据英国统计局数据&#xff0c;英国5月核心CPI年率为3.5%&#xff0c;低于前值3.9%&#xff1b;英国5月名义CPI年率为2%&#xff0c;低于前值2.3%。核心CPI年率和名义CPI年率相比前值分别下降0.4个百分点和0.3百分点&#xff0c;意味着英国的通胀率仍处于快…

android中的JNI的DEMO

一&#xff1a;源代码 native-lib.cpp #include "native-lib.h"JNIEXPORT jint JNICALL Java_com_example_jnidemo_MainActivity_add(JNIEnv* env, jobject, jint a, jint b) {return a b; }JNIEXPORT jint JNICALL Java_com_example_jnidemo_MainActivity_subtra…

【Win】双系统新体验:Hyper-V上macOS安装攻略

在虚拟化的世界里&#xff0c;Hyper-V是探索不同操作系统的一扇大门。尽管macOS并不是Hyper-V官方支持的来宾操作系统&#xff0c;但这并未阻挡技术探索者的脚步。他们通过不懈努力&#xff0c;开辟出了一条条通往macOS的非官方路径。这些路径或许曲折&#xff0c;却为那些渴望…

《QT从基础到进阶·七十二》基于Qt开发的文件保险柜工具并支持文件各种加密和解密

1、概述 源码放在文章末尾 该项目实现了文件各种加密和解密的功能&#xff0c;能够有效的保障文件的安全&#xff0c;主要包含如下功能&#xff1a; 1、支持所有 AES 密钥长度&#xff1b; AES_128 AES_192 AES_256 2、支持ECB、CBC、CFB、OFB四种模式&#xff1b; 3、支持ZER…

【学习】程序员资源网站

1 书栈网 简介&#xff1a;书栈网是程序员互联网IT开源编程书籍、资源免费阅读的网站&#xff0c;在书栈网你可以找到很多书籍、笔记资源。在这里&#xff0c;你可以根据热门收藏和阅读查看大家都在看什么&#xff0c;也可以根据技术栈分类找到对应模块的编程资源&#xff0c;…