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

 一、前言

在探索 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学习资料,请点击→

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

欢度盛夏,畅享清凉——七月超市营销策略

随着七月的到来,我国大部分地区进入夏季,气温逐渐攀升,消费者们对清凉、消暑产品的需求也随之增长。在这个夏日,超市应该如何抓住这一商机,提升销售业绩呢?本文将从商品陈列、促销活动等方面,为…

docker安装rabbitmq和延迟插件(不废话版)

1.下载镜像 docker pull rabbitmq:3.8-management 2.启动 docker run -e RABBITMQ_DEFAULT_USERlicoos -e RABBITMQ_DEFAULT_PASSlicoosrabbitmq -v mq-plugins:/plugins --name mq --hostname mq -p 15672:15672 -p 5672:5672 -d rabbitmq:3.8-management 3.下载对…

基于SpringBoot的社区医院管理服务系统

开头语:你好呀,我是计算机学姐码农小野!如果有相关需求,可以私信联系我。 开发语言:Java 数据库:MySQL 技术:SpringBoot框架 工具:Eclipse,Navicat,Maven…

Mobvista汇量科技解析奥运机会点及营销理念,看广告投放如何抢占先机

四年一度的奥运盛会,作为少有能跨越文化、宗教、种族、行为等各方面差异的体育事件,更能广泛吸引全球观众的目光,成为品牌方和广告主天然的流量磁铁。应用增长平台Mobvista汇量科技为助力各行业开发者、各品牌商家抢占奥运流量,分…

mp4怎么转换成mp3?这四种转换方法你肯定能用到!

mp4怎么转换成mp3?MP4,这一广为人知的数字多媒体文件格式,无疑已经成为了当下最受欢迎的选择之一,但你是否深入了解过它背后的魅力所在呢?今天,就让我为你揭开MP4的神秘面纱,首先,MP…

ThinkPHP5大学生社会实践管理系统

有需要请加文章底部Q哦 可远程调试 ThinkPHP5大学生社会实践管理系统 一 介绍 大学生社会实践管理系统基于ThinkPHP5框架开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈:ThinkPHP5mysqlbootstrapphpstudyvscode 二 功…

10 种语言文本准确渲染;Mac无需联网的本地聊天应用;多模态语言模型(MLM)基准测试的引擎;Yolo DotNet版本

✨ 1: Glyph-ByT5 10 种语言文本准确渲染,将文本渲染的准确性从提高到近 90% ,同时还能实现段落渲染自动布局 Glyph-ByT5是一种定制的文本编码器,旨在实现准确的文字视觉渲染。其核心思想是通过细致的字形-文本配对数据集的微调&#xff0c…

商淘云:服装实体店引流会员营销方案

服装零售实体店面临着越来越大的挑战,尤其是在吸引和保持忠诚顾客方面。为了应对这一挑战,制定一套有效的引流会员营销方案显得尤为重要。商淘云将探讨如何通过创新的营销策略和增强的顾客体验,提升实体店的会员数量和销售业绩,从…

【精品方案】产业园区数字孪生规划方案(39页PPT)

引言:随着数字化和智能化技术的快速发展,传统产业园区面临着转型升级的重大机遇。数字孪生技术作为一种将物理世界与数字世界紧密结合的创新技术,为产业园区的规划、建设和运营管理提供了全新的解决方案。本方案旨在通过构建产业园区数字孪生…

C# WinForm —— 36 布局控件 GroupBox 和 Panel

1. 简介 两个可以盛放其他控件的容器,可以用于把不同的控件分组,一般不会注册事件 GroupBox:为其他控件提供可识别的分组。可通过Text属性设置标题;有边框;没有滚动条,一般用于按功能分组 Panel&#xff…

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

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

设计模式(七)创建者模式之建造者模式

这里写目录标题 概述需求需求类图BikeBuilderMobikeBuilderOfoBuilderDirectorClientClient优缺点使用场景 模式扩展ComputerClient创建者模式对比工厂方法模式VS建造者模式抽象工厂模式VS建造者模式 总结 概述 建造者模式又叫生成器模式,是一种对象构建模式。它可…

2021数学建模A题目–“FAST”主动反射面的形状调节

A 题——“FAST”主动反射面的形状调节 思路:该题主要是通过利用伸缩杆调整FAST反射面,给出合适的调整方案 程序获取 第一题问题思路与结果: 当待观测天体S位于基准球面正上方,结合考虑反射面板调节因素,确定理想抛物…

k8s上尝试滚动更新和回滚

滚动更新和回滚 实验目标: 学习如何进行应用的滚动更新和回滚操作。 实验步骤: 创建一个 Deployment。更新 Deployment 的镜像版本,观察滚动更新过程。回滚到之前的版本,验证回滚操作。 今天呢,我们继续来进行我们k…

棱镜七彩荣获CNNVD两项大奖,专业能力与贡献再获认可!

6月18日,国家信息安全漏洞库(CNNVD)2023年度工作总结暨优秀表彰大会在中国信息安全测评中心成功举办。棱镜七彩凭借在漏洞方面的突出贡献和出色表现,被授予“2023年度优秀技术支撑单位”与“2023年度最佳新秀奖”。 优秀技术支撑单…

Windows安装配置jdk和maven(仅做记录)

他妈的远程连接不上公司电脑,只能在家重新配置一遍,在此记录一下后端环境全部配置 Windows安装配置JDK 1.8一、下载 JDK 1.8二、配置环境变量三、验证安装 Windows安装配置Maven 3.8.8一、下载安装 Maven并配置环境变量二、设置仓库镜像及本地仓库三、测…

构建LangChain应用程序的示例代码:38、自主RAG的概念及其实现方法,使用LangChain和OpenAI工具从头开始构建一个结合检索和生成的系统

# 安装必要的库 ! pip install langchain_community tiktoken langchain-openai langchainhub chromadb langchain langgraph自主RAG (Self-RAG) 自主RAG是最近的一篇论文,介绍了一种用于主动RAG的有趣方法。 该框架训练单个任意的语言模型(如LLaMA2-7…

科技赋能冷链园区:可视化带来全新体验

应用图扑可视化技术,冷链园区能够更加直观地监控和管理资源,优化运作流程,提高运营效率与服务质量。

机器学习课程复习——支持向量机

支持向量机是一种二类分类模型。基本模型:定义在特征空间上的间隔最大的线性分类器模型升级:线性分类器+核技巧=非线性分类器学习策略:间隔最大化(可形式化为求解凸二次规划的问题;可等价于正则化的合页损失函数的最小化问题)学习算法:求解图二次规划的最优化算法支持向…

三次输错密码后,系统是怎么做到不让我继续尝试的?

1故事背景 忘记密码这件事,相信绝大多数人都遇到过,输一次错一次,错到几次以上,就不允许你继续尝试了。 但当你尝试重置密码,又发现新密码不能和原密码重复: 图片 相信此刻心情只能用一张图形容: 图片 虽然,但是,密码还是很重要的,顺便我有了一个问题:三次输错密…