华为仓颉鸿蒙HarmonyOS NEXT原生UI状态管理(类似SwiftUI和Flutter的状态管理)

本文篇幅较长,建议点赞收藏,以免找不到哟(^U^)ノ~YO

Flutter的状态管理:

setState()方法:Flutter中最简单的状态管理方式是使用setState()方法来通知Flutter框架重新构建UI以反映新的状态。

Provider:Provider是Flutter社区广泛使用的状态管理库,它提供了一种简单而有效的方式来管理应用的状态,并支持依赖注入和消费者模式。

Bloc:Bloc是一种基于事件驱动的状态管理库,它有助于将业务逻辑与UI分离,并使状态管理更加结构化。

GetX:GetX是另一个轻量级且高性能的状态管理工具,它提供了便捷的方式来管理状态、路由和依赖注入。

SwiftUI的状态管理:

@State和@Binding:SwiftUI通过@State和@Binding属性包装器来管理界面组件的状态,并实现UI的响应式更新。

ObservableObject和@ObservedObject:SwiftUI还支持ObservableObject协议和@ObservedObject属性包装器,用于管理应用的全局状态和数据流。

Combine:SwiftUI结合了Combine框架,可以使用Publishers和Subscribers来处理数据流和响应式编程。

Redux:虽然不是官方支持的方式,但在SwiftUI中也可以使用Redux架构来管理复杂的状态

仓颉的状态管理具体如下:

@Entry

@Entry 用于指明当前页面的入口组件,仅能装饰在被 @Component 修饰的子组件上。一个文件最多只能有一个 @Entry

示例

@Entry
    @Component
    class ParentComponent {
        func build() {
            Column {
                Text("")
            }
        }
    }

@Component

@Component 用于修饰可重用的 UI 单元,该单元必须为 Class 类型。被修饰的class能够成为一个单独的组件,也被称为自定义组件。在render函数中描述UI结构。

  • 自定义组件中的成员变量必须声明类型
  • 自定义组件必须实现render函数
  • 自定义组件禁止自定义构造函数
  • 自定义组件禁止继承
  • 自定义组件禁止使用泛型

示例:

@Component
    class ParentComponent {
        func build() {
            Column {
                Text("")
            }
        }
    }

自定义组件可以在其他组件中使用

@Component
    class SubComponent {
        func build() {
            Column {
                Text("")
            }
        }
    }


    @Component
    class ParentComponent {
        func build() {
            Column {
                Text("")
                SubComponent()
            }
        }
    }

如果类中有成员变量,可以通过命名参数传值。其中,对于没有初始值的成员变量,必须在创建实例的时候传值( @Consume 装饰的变量除外),有初始值的则可以选择性地传值;对于let修饰的且带有初始值的成员变量,则不可在创建实例的时候传值。

@Component
    class SubComponent {
        @Link var cnt: Int64
        let innerCnt = 0
        var count: Int64 = 0
        func build() {
            Column {
                Text("")
            }
        }
    }


    @Component
    class ParentComponent {
        @State var cnt: Int64 = 0
        func build() {
            Column {
                Text("")
                SubComponent() // Error cnt没有初始化
                SubComponent(cnt: cnt) // OK count有初始值,可以不传值
                SubComponent(cnt: cnt, innerCnt: cnt) // Error innerCnt不可通过构造传值
            }
        }
    }

@State

@State 修饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的render刷新。

被 @State 修饰的成员变量必须指明类型和初始值。由于状态是需要被更改的数据,所以对于被 @State 修饰的变量必须通过 var 来声明,不能使用 let。

  • 支持多种类型:支持基础数据类型:char、UInt8/16/32/64、Int8/16/32/64、Float16/32/64、Bool、String、Enum、Struct等;支持类类型和数组类型,但是如果要感知内部的变化,对于类类型,在定义的时候需要被@Observed修饰(详见@Observed和@Publish一节);对于数组类型则需要使用ObservedArray和ObservedArrayList,详见ObservedArray和ObservedArrayList一节。
  • 私有:仅在组件内访问;不可被 public protected 等修饰符修饰;
  • 支持多个实例:一个组件中可以定义多个标有 @State的属性;
  • 需要本地初始化:必须为所有 @State 变量分配初始值。
  • 创建自定义组件时支持通过状态变量名设置初始值:在创建组件实例时,可以通过变量名显式指定 @State状态属性的初始值。

示例

@Entry
    @Component
    class ParentComponent {
        @State var count: ObservedArrayList<T> = 0
        func build() {
            Column {
                Button("This is a case of @State ${count}")
                .onClick({evt =>
                    count[0] = 9
                })
            }
        }
    }

@Link

@Link 与 @State 有相同的语义,但初始化方式不同。 @Link 装饰的变量必须使用其父组件提供的变量进行初始化,被 @Link 修饰的成员变量必须指明类型,且只能使用 var 来声明。允许组件内部修改 @Link 变量,且更改会通知给父组件,即 @Link 属于双向数据绑定。 @Link 修饰当前组件所拥有的状态,仅可在子组件中定义。

  • 支持多种类型: @Link 变量的值与 @State 变量的类型相同。
  • 私有:仅在组件内访问;不可被 public protected 等修饰符修饰;
  • 支持多个实例:一个组件中可以定义多个标有 @Link 的属性;
  • 双向通信:子组件对 @Link 变量的更改将同步修改父组件的 @State 变量;

示例

@Component
    class SubSubComponent {
        @Link var count: Int64
        var commonCount: Int64 = 0
        func build() {
            Column {
                Button("This is a case of @Link ${count} _____ SubSubComponent ${commonCount}").onClick({evt =>
                    count = count + 1
                })
            }
        }
    }


    @Component
    class SubComponent {
        @Link var count: Int64
        func build() {
            Column {
                Button("This is a case of @Link ${count} _____ SubComponent")
                .onClick({evt =>
                    count = count + 1
                })
                SubSubComponent(count: count, commonCount: count)
            }
        }
    }


    @Entry
    @Component
    class ParentComponent {
        @State var count: Int64 = 0
        func build() {
            Column {
                Button("This is a case of @Link ${count} _____ ParentComponent")
                .onClick({evt =>
                    count = count + 1
                })
                SubComponent(count: count)
            }
        }
    }

@Prop

@Prop 与 @State 有相同的语义,但初始化方式不同。 @Prop 装饰的变量必须使用其父组件提供的变量进行初始化,被 @Prop 修饰的成员变量必须指明类型,且只能使用 var 来声明。允许组件内部修改 @Prop 变量,但更改不会通知给父组件,即 @Prop 属于单向数据绑定。 @Prop 修饰当前组件所拥有的状态,仅可在子组件中定义。

@Prop 状态数据具有以下特征:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值