@State 自己的状态
注意:不是状态变量的所有更改都会引起刷新。只有可以被框架观察到的修改才会引起UI刷新。
1、boolean、string、number类型时,可以观察到数值的变化。
2、class或者Object时,可以观察 自身的赋值 的变化,第一层属性赋值的变化,即Object.keys(observedObject)返回的属性。
源代码:
index.ets:
import { componentUtils } from '@kit.ArkUI' interface Car { name: string } interface Person { name: string, car: Car } const obj: Person = { name: 'zs', car: { name: '小黄车' } } console.log('查看第一层属性',Object.keys(obj)) @Entry @Component struct Index { // 状态变量 // 1、string number boolean可以直接监视到变化 @State message: string = 'hello world' // 2、复杂类型 object class 第一层随便改,嵌套的话需要进行整个嵌套对象的替换 @State person: Person = { name: 'jack', car: { name: '宝马车' } } build() { Column({space: 10}) { Text(this.message).fontSize(20) Button('改message').onClick(() => { this.message = '你好' }) Text(JSON.stringify(this.person)) Button('改person').onClick(() => { // 1、全部修改可以 // this.person = { // name: 'any', // car: { // name: '保时捷' // } // } // 2、修改name // this.person.name = 'tony' 修改第一层name可以 // 如果不是对象的第一层属性,修改时,需要修改整个对象嵌套的对象,否则页面不会刷新,但是值已经改了 // this.person.car.name = '小火车' // 页面检测不到 // console.log('car name', this.person.car.name ) // this.person.car = { // name: '小火车' // } }) } .width('100%') .height('100%') .padding(20) .backgroundColor('#ccc') } }
效果图:
@Prop 父子
@Prop - 父子单向
@Prop 装饰的变量可以和父组件建立单向的同步关系。
@Prop 装饰的变量是可变的,但是变化不会同步回其父组件。
源代码:
import { componentUtils } from '@kit.ArkUI' @Component struct SonCom { // 保证父组件的数据变化了,能够往下响应式的更新 @Prop sCar: string = '' changeCar = ()=> { } build() { Column({space: 10}) { Text(`子组件 - ${this.sCar}`) Button('换车').onClick(() => { // 1、prop传值是单向传递 // 子组件可以修改到 prop 传值,但是修改的更新不会同步到父组件 // 通常不太会直接修改 prop 传值,因为父组件的状态一旦变化,会自动向下同步 // this.sCar = '小黄车' // 2、如果实在想更新,希望保证父子同步 => 调用父组件传递过来的方法 // 如果没有写箭头函数,意味着,this 指向调用者,而此处执行环境this -> 子组件 this.changeCar() }) } .padding(20) .backgroundColor(Color.Orange) } } @Entry @Component struct FatherCom { @State fCar: string = '劳斯莱斯' build() { Column({space: 10}) { Text(`父组件 - ${this.fCar}`) Button('换车').onClick(() => { this.fCar = '三轮车' }) // 子组件 SonCom({ sCar: this.fCar, // 这里必须要用箭头函数,否则会有 this 指向的问题 // 使用箭头函数的好处,会使用外部环境的this,不受传递过去的执行环境影响 // 希望此处 this 指向的是父组件 // changeCar(){ changeCar: ()=> { console.log('这里可以写具体的业务逻辑') this.fCar = '超级大赛车' } }) } .padding(50) .backgroundColor(Color.Pink) } }
效果图:
@Prop 父向子练习
传参:
import { componentUtils } from '@kit.ArkUI' @Component struct SonCom { // 保证父组件的数据变化了,能够往下响应式的更新 @Prop sCar: string = '' changeCar = (newCar: string)=> { } build() { Column({space: 10}) { Text(`子组件 - ${this.sCar}`) Button('换车').onClick(() => { // 1、prop传值是单向传递 // 子组件可以修改到 prop 传值,但是修改的更新不会同步到父组件 // 通常不太会直接修改 prop 传值,因为父组件的状态一旦变化,会自动向下同步 // this.sCar = '小黄车' // 2、如果实在想更新,希望保证父子同步 => 调用父组件传递过来的方法 // 如果没有写箭头函数,意味着,this 指向调用者,而此处执行环境this -> 子组件 this.changeCar('老爷车') }) } .padding(20) .backgroundColor(Color.Orange) } } @Entry @Component struct FatherCom { @State fCar: string = '劳斯莱斯' build() { Column({space: 10}) { Text(`父组件 - ${this.fCar}`) Button('换车').onClick(() => { this.fCar = '三轮车' }) // 子组件 SonCom({ sCar: this.fCar, // 这里必须要用箭头函数,否则会有 this 指向的问题 // 使用箭头函数的好处,会使用外部环境的this,不受传递过去的执行环境影响 // 希望此处 this 指向的是父组件 // changeCar(){ changeCar: (newCar: string)=> { console.log('这里可以写具体的业务逻辑') this.fCar = newCar } }) } .padding(50) .backgroundColor(Color.Pink) } }
@Prop 父向子 练习二
import { componentUtils } from '@kit.ArkUI' // comp @Component struct NumberCount { @Prop num: number = 1 subFn = ()=> { } addFn = ()=> { } build() { // 数字框组件 Row({ space: 5 }) { Button('-').onClick(() => { this.subFn() }) Text(this.num.toString()) Button('+').onClick(() => { this.addFn() }) } } } @Entry @Component struct Index { @State num1: number = 5 @State num2: number = 3 build() { Column() { Row() { Text('茄子') NumberCount({ num: this.num1, addFn: () => { this.num1++ }, subFn: ()=> { this.num1-- }}) } Row() { Text('香蕉') NumberCount({ num: this.num2, addFn: () => { this.num2++ }, subFn: ()=> { this.num2++ }}) } } } }
效果图: