3

OpenHarmony—浅析ETS开发状态管理

 2 years ago
source link: https://os.51cto.com/article/703358.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
OpenHarmony—浅析ETS开发状态管理-51CTO.COM
OpenHarmony—浅析ETS开发状态管理
作者:杨保斌 2022-03-07 15:22:16
本文主要对于使用class定义复杂数据,以及跨组件传值、修改数据根据官方文档进行简单解析。

955a26846b6ba65459c257c96f16fa244b30a7.png

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

本文主要是对于鸿蒙开发文档 ETS 开发中的 UI状态管理部分进行解读和简单的实践,方便更快的切入开发工作,构建应用,对应文档链接:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-ui-state-mgmt-concepts-0000001169868220。

鸿蒙状态管理简介

首先引用开发文档中的图片,图片中已经基本可以看出整个应用中的数据流动,非常全面。

798f971966a8139d3da020b6694aa0df7144e4.png

华为鸿蒙开发文档对于应用中状态的管理提供了丰富且全面的接口(仅提供通俗理解,具体定义见文档):

  • @State:用于定义应用管理的状态,更像是React16.8之后的useState,方便代码根据业务划分逻辑,状态定义仅支持class、number、boolean、string 及其组成的数组,并不允许object和any。
  • @Props:单项数据流,父组件传递子组件,直接使用this.属性名向下传递数据,子组件使用此修饰器接收,推荐用于只渲染的数据用此定义。
  • @Link:双向数据流,解决了vue中**emit**函数的功能,父组件用emit∗∗函数的功能,父组件用向下传递数据,子组件使用此修饰器接收,推荐需要在子组件中修改父组件状态的情况(即为类似于在vue中需要使用$emit)下使用。
  • @Consume和**@Provide**: 其中provide是生产者,consume是消费者,写过react的开发者应该对此很熟悉,类似于react中的context上下文,这一对修饰器主要实现的是上层组件跨多层传值给下层组件,并实现双向绑定数据。
  • @Observed和**@ObjectLink**:其中@Observed用于修饰类,@ObjectLink用于在子组件中修饰已经被@Observed修饰的类对应的状态(具体用法见下文),这一对修饰器主要解决的问题是,如果定义了一个包含多个对象(类)的数组,其中对象的属性发生变化,能够被应用监测到并更新视图。
  • @Watch:在某一可被应用监测的状态发生修改的时候,执行某个额外的动作。
  • AppStorage:
  1. 应用程序中的单例对象,由UI框架在应用程序启动时创建,在应用程序退出时销毁,为应用程序范围内的可变状态属性提供中央存储,简单来说就类似于vuex/redux。
  2. 上述几个状态管理的修饰器,更多的是在同一个page中去使用,根据业务/页面逻辑划分组件,实现状态管理,父子组件传值,跨组件传值等。
  3. 而AppStorage是在多页面(page文件夹下有多个@Enter定义页面)应用程序中用于跨页面共享数据。
  4. 建议AppStorage的使用在有@Enter的组件中使用,其中的数据在组件树中从顶部注入,对子组件来说只是一个父组件传递过来的状态,保证子组件的职能单一,输入输出稳定,与外部数据解耦,保证复用性。

梦开始的地方(Typescript而非anyscript)

本文主要是对于复杂数据类型class的使用解读,对于number/boolean/string暂不做解读,请自行尝试。

一切都是从class开始的:@State定义中明确表示只能class、number、boolean、string 及其组成的数组,并不允许object和any,所以对于复杂数据类型的定义就需要用到class,如下图:

定义接口:

556150302667ada6a0808766ae0cf078f0b77e.png

使用接口定义复杂数据(此处例子可以看出,用**new Month( )或者直接{ }**都是可以的)。

63f172526579d7cb557833e993969f4e94983a.png

这里引用了官方文档https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ts-rending-control-syntax-foreach-0000001149978669中的例子,根据本文档中的例子可以看出,使用class可以定义复杂数据类型,并且其中Month8的属性在任何地方改变都可以被observe到,calendar中使用数组方法改变数组也能被observe到,并且触发重渲染。

非常不推荐使用**any[ ]**的方式来定义复杂数据,这样定义的数据不会被应用observe到,数组发生改变,不会引发视图更新!

使用class定义的数据可以使用@Props和@Link向下传递数据,如下图,在second组件中修改calendar是生效的。

  • 将class定义的数据传递给子组件。

250f5c916a37d982a41259a9d2a514c97b4430.png

  • 子组件双向绑定改变状态!

b3a3dea9225647f5572450492af18e9be3bdb6.png

6640d23137c853d0e615435f3f380bfff9e948.png

e6f270941b9407e7343793a9e0313e58f08c1e.png

跨组件传值(@Consume和@Provide)

类似于react中的context上下文实现跨组件传值,上层组件的状态可以直接传给最下层组件,非常好用。

我们已经有了@Props和@Link解决了简单的父子组件传值,文档同样提供了跨组件传值的方法,@Provide可以直接替换掉@State定义状态,@consume可以在需要接收的子组件中拿到传递下来的状态。

定义状态:

847ca1089ec438049a70270c0512ac2d29f27c.png

使用并渲染,并尝试改变,(其实传给下一层还是下下层使用和效果上没啥区别)。

8916491245d35e5b01325304cf7346c29eac2c.png

688ddc8157fcf420450903214ff052108f1e04.png

当然传给第三层也可以看一下效果:

e72ded1636a026d74e9935d3472b86f79c125e.png

渲染结果:

68c4588236809972e8f77825afd5f2011ce02f.png

在子组件中修改数组。

316134096e7ae0503f9848a27eed7fae22eff0.png

在子组件中修改对象中的属性。

d48a60a02b4b025904a333b635de05d6b923ab.png

在子组件中修改数组中的对象的属性(此方法失败,状态改变了,但是并没有渲染,这是有问题的),正确方法见下文。

b788c299106545bc9b92683660a2b10ef1841e.png

神奇的@Observed和@ObjectLink

@Observed是用来修饰类的,能够帮忙监测多层数据中的数据变化,官方文档中已经给出了具体的使用方法,而且非常灵活,这一对修饰器主要解决的正是上述遗留问题,如何修改数组中的对象中的属性,并能够自动触发重渲染。

使用@Observed:

a5622da086999c80aff2262ee976eb568e215d.png

使用@ObjectLink,这里主要是验证用provider/link传递到下层的数据能否被修改。

e267931688ced82173146646cf9062564bf166.png

e65182d555d5c53c787485e70602b11225ffd5.png

132fd4b42535f95fab8536ba088dec25cfd095.png

52e73be28a159a51a0007830770406d1dd762c.png

0422bb3359061d8f4654859ddb940ffd12bd50.png

从上述案例可以看出:使用@Observed和@ObjectLink可以实现对比较复杂的数据最内部数据的修改,使用起来相对灵活。

本文主要对于使用class定义复杂数据,以及跨组件传值、修改数据根据官方文档进行简单解析,对于状态管理还包括AppStorage、持久化数据以及环境变量的验证,将会在下一篇文章中做出详解,希望本篇文章能够在一定程度上帮助初学ets的开发者快速掌握其开发方式。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK