状体管理-装饰器

@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++
        }})
      }
    }
  }
}

效果图:

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值