@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 = 1subFn = ()=> {}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 = 3build() {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++}})}}} }
效果图: