本文篇幅较长,建议点赞收藏,以免找不到哟(^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 状态数据具有以下特征: