HarmonyOS NEXT 实战系列04-组件状态

自定义组件拥有变量,变量必须被装饰器装饰才可以成为状态变量,状态变量的改变会引起UI的渲染刷新。如果不使用状态变量,UI只能在初始化时渲染,后续将不会再刷新。 下图展示了State和View(UI)之间的关系。

View(UI):UI渲染,指将build方法内的UI描述和@Builder装饰的方法内的UI描述映射到界面。

State:状态,指驱动UI更新的数据。用户通过触发组件的事件方法,改变状态数据。状态数据的改变,引起UI的重新渲染。

1. 组件状态-@State

@State装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就可以触发其直接绑定UI组件的刷新。当状态改变时,UI会发生对应的渲染改变。

简单类型变量

@Entry

@Component

struct TestPage {

@State

count: number = 0

build() {

Column({ space: 50 }) {

Row() {

Text('-')

.textButton()

.onClick(() => {

this.count--

})

Text(this.count.toString())

.padding(15)

Text('+')

.textButton()

.onClick(() => {

this.count++

})

}

}

.width('100%')

.height('100%')

.margin({ top: 50 })

}

}

@Extend(Text)

function textButton() {

.fontSize(20)

.backgroundColor('#CCCCCC')

.width(32)

.aspectRatio(1)

.borderRadius(16)

.textAlign(TextAlign.Center)

}

对象类型变量

@Entry

@Component

struct TestPage {

@State

students: string[] = ['小红', '小明']

build() {

Column({ space: 10 }) {

ForEach(this.students, (item: string, i) => {

Row({ space: 10 }){

Text(item)

Text('-')

.textButton()

.onClick(() => {

// 从索引x处,删除x条

this.students.splice(i, 1)

})

}

})

Button('添加学生')

.onClick(() => {

// 追加

this.students.push('小芳')

})

}

}

.width('100%')

.height('100%')

.margin({ top: 50 })

}

}

@Extend(Text)

function textButton() {

.fontSize(20)

.backgroundColor('#CCCCCC')

.width(32)

.aspectRatio(1)

.borderRadius(16)

.textAlign(TextAlign.Center)

}

数组类型变量

interface Person {

name: string

age: number

}

@Entry

@Component

struct TestPage {

@State

person: Person = { name: 'Jack', age: 18 }

build() {

Column({ space: 50 }) {

Row({ space: 10 }){

Text(this.person.name)

Text(this.person.age.toString())

Button('明年')

.onClick(() => {

this.person.age ++

})

}

}

.width('100%')

.height('100%')

.margin({ top: 50 })

}

}

2. 组件状态-@Prop

@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

1)自定义组件

在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。

可组合:允许开发者组合使用系统组件、及其属性和方法。

可重用:自定义组件可以被其他组件重用,并作为不同的实例在不同的父组件或容器中使用。

数据驱动UI更新:通过状态变量的改变,来驱动UI的刷新。

@Component

struct MyComponent {

build() {

// 组件结构

}

}

尝试:提取 counter 组件

@Entry

@Component

struct TestPage {

build() {

Column({ space: 50 }) {

CounterComp()

CounterComp()

}

.width('100%')

.height('100%')

.margin({ top: 50 })

}

}

@Component

struct CounterComp {

@State count: number = 0

build() {

Row() {

Text('-')

.textButton()

.onClick(() => {

this.count--

})

Text(this.count.toString())

.padding(15)

Text('+')

.textButton()

.onClick(() => {

this.count++

})

}

}

}

@Extend(Text)

function textButton() {

.fontSize(20)

.backgroundColor('#CCCCCC')

.width(32)

.aspectRatio(1)

.borderRadius(16)

.textAlign(TextAlign.Center)

}

2)父子单向同步

@Entry

@Component

struct TestPage {

@State count: number = 0

build() {

Column({ space: 50 }) {

// Prop 父传值给子

CounterComp({ count: this.count })

CounterComp({ count: this.count })

}

.width('100%')

.height('100%')

.margin({ top: 50 })

}

}

@Component

struct CounterComp {

@Prop @Require count: number

build() {

Row() {

Text('-')

.textButton()

.onClick(() => {

this.count--

})

Text(this.count.toString())

.padding(15)

Text('+')

.textButton()

.onClick(() => {

this.count++

})

}

}

}

@Extend(Text)

function textButton() {

.fontSize(20)

.backgroundColor('#CCCCCC')

.width(32)

.aspectRatio(1)

.borderRadius(16)

.textAlign(TextAlign.Center)

}

注意:

虽然 @Prop 修饰的状态不会同步到父,但是字组件UI是会影响的

可以加上 @Require 代表必传,可省略初始值

3. 组件状态-@Link

子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。

@Entry

@Component

struct TestPage {

@State count: number = 0

build() {

Column({ space: 50 }) {

// Link 父同步子,子同步父

CounterComp({ count: this.count })

CounterComp({ count: this.count })

}

.width('100%')

.height('100%')

.margin({ top: 50 })

}

}

@Component

struct CounterComp {

@Link count: number

build() {

Row() {

Text('-')

.textButton()

.onClick(() => {

this.count--

})

Text(this.count.toString())

.padding(15)

Text('+')

.textButton()

.onClick(() => {

this.count++

})

}

}

}

@Extend(Text)

function textButton() {

.fontSize(20)

.backgroundColor('#CCCCCC')

.width(32)

.aspectRatio(1)

.borderRadius(16)

.textAlign(TextAlign.Center)

}

————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/zsgzsgzsgzsgzsg/article/details/146183945

全部评论

相关推荐

程序员花海:实习和校招简历正确格式应该是教育背景+实习+项目经历+个人评价 其中项目经历注意要体现业务 实习经历里面的业务更是要自圆其说 简历模板尽可能保持干净整洁 不要太花哨的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务