美文网首页
组件状态共享

组件状态共享

作者: 家乡的蝈蝈 | 来源:发表于2024-01-24 11:26 被阅读0次

    1、组件状态共享

      State是当前组件的状态, 用State修饰的数据变化会驱动UI的更新(只有第一层)
      父传子的时候,子组件定义变量的时候,如果没有任何的修饰符,那么该值只会在第一次渲染时生效

    1.1、状态共享-父子单向

      @Prop 装饰的变量可以和父组件建立单向的同步关系。@Prop 装饰的变量是可变的,但是变化不会同步回其父组件。-Prop是用在子组件中的
      Prop只能修饰string number boolean类型的数据- (Next全部都支持了各种类型)

    • 完成父 - 子的单向同步
    @Entry
    @Component
    struct PropCase {
      @State message: string = 'Hello World'
      @State num:number = 0
      build() {
        Row() {
          Column({space:20}) {
            Text(this.num.toString()).fontSize(50).fontWeight(FontWeight.Bold)
              .onClick(() => {
                this.num++
              })
            Divider()
              .strokeWidth(6)
            Child({num:this.num})
    
          }
          .width('100%')
        }
        .height('100%')
      }
    }
    
    @Component
    struct Child {
      @Prop
      num:number
      build() {
        Text(this.num.toString()).fontSize(40).fontColor(Color.Red)
          .onClick(() => {
            this.num++
          })
      }
    }
    

      我们发现使用Prop修饰的状态,只会在当前子组件生效,不会传导到父组件,所以它属于一种单向传递

    • 支持类型 string、number、boolean、enum 类型- 下个版本支持的类型更多
    • 子组件可修改 Prop 数据值,但不同步到父组件,父组件更新后覆盖子组件 Prop 数据
    • 子组件可以初始化默认值,注意:目前编译器会提示错误,请忽略,下个版本将修复

    1.2、状态共享-父子双向

    • Prop修饰符- 父组件数据更新-让子组件更新- 子组件更新-父组件不为所动
        Prop是单向的,而Link修饰符则是双向的数据传递,只要使用Link修饰了传递过来的数据,这个时候就是双向同步了
      注意点:在父组件传入Link属性时,需要使用$来修饰该变量,去掉this
    Child({num:$num})
    @Link num:number
    // 子组件中被@Link装饰的变量与其父组件中对应的数据源建立双向数据绑定
    

      需要注意的是,Link修饰的变量类型变得更为宽泛,支持string、number、boolean、enum Object Class以及这些类型对应的数组
    小结:
    调试技巧:

    • console.log('vc-----:'+'')加前缀
    • 可以使用弹出信息的方式-或者显示文本到页面的形式
      // AlertDialog.show({message:this.commentStr}) // alert弹窗
      Text(JSON.stringfiy())

    ArkTS所有的响应式更新都只能监听到我们的第一层数据
    Link修饰的数据必须得是最外层的 State数据

    @Entry
    @Component
    struct LinkCase {
      @State message: string = 'Hello World'
      @State
      list:FoodClass[] =  [{
        order_id: 1,
        food_name: '鱼香肉丝',
        food_price: 18.8,
        food_count: 1
      },{
        order_id: 2,
        food_name: '粗溜丸子',
        food_price: 26,
        food_count: 2
      },{
        order_id: 3,
        food_name: '杂粮煎饼',
        food_price: 12,
        food_count: 1
      }]
      build() {
        Row() {
          Column({space:20}) {
            ForEach(this.list, (item:FoodClass)=>{
              Row() {
                Text(item.food_name).TextStyle()
                Text(item.food_price.toFixed(2)).TextStyle()
                Text(item.food_count.toString()).TextStyle()
              }
              .height(40)
              .width('100%')
            })
            BottonCard({myList:$list}) // 记得传过去的数据要被state修饰
      // Link修饰的数据必须得是最外层的 State数据,如果没有被state修饰,后续ObjectLink 和Observerd会解决这个问题
    
          }
          .width('100%')
        }
        .height('100%')
      }
    }
    
    @Extend(Text)
    function TextStyle() {
      .layoutWeight(1).textAlign(TextAlign.Center).fontSize(20)
    }
    // 食品类
    class FoodClass {
      order_id: number = 0
      food_name:  string = ""
      food_price: number = 0
      food_count: number = 0
    }
    @Component
    struct BottonCard {
      @Link
      myList:FoodClass[]
      build() {
        Button('更改菜品的数量')
          .onClick(() => {
            // map循环数组返回新数组,map中item代表数组中的元素,map会将其中的item组成一个新的数组
            this.myList = this.myList.map(item => {
              item.food_count++
              return item
            })
          })
      }
    }
    

    1.2、状态共享-后代组件

      如果我们的组件层级特别多,ArkTS支持跨组件传递状态数据来实现双向同步@Provide和 @Consume
      变量包括Object、class、string、number、boolean、enum 类型均支持@Provide和 @Consume
      例子:假设我们有三层组件,Index-Child-Grand, Index的数据不想经过Child而直接给到Grand可以使用该修饰器

    1.2.1、通过相同的变量名绑定

    @Entry
    @Component
    struct ProvideCase {
      @Provide money:number = 1000 // Provide跨组件提供数据,实现双向绑定,爷爷提供数据
      build() {
        Row() {
          Column({space:20}) {
            Text(`爷爷的钱:${this.money.toString()}`).fontSize(30)
            Divider().strokeWidth(3).color(Color.Red)
            Father()
          }
          .width('100%')
        }
        .height('100%')
      }
    }
    
    @Component
    struct Father {
      @Consume money:number
      build() {
        Column() {
          Text('父亲组件').fontSize(30)
            .onClick(() => {
              this.money += 2
            })
          Divider().strokeWidth(3).color(Color.Green)
          GreateSon()
        }
      }
    }
    
    @Component
    struct GreateSon {
      @Consume
      money:number // Consume跨组件接收数据,实现双向绑定
      build() {
        Text(`接收到爷爷的钱:${this.money.toString()}`)
          .fontSize(20)
          .onClick(() => {
            this.money -= 10
          })
      }
    }
    

    注意: 在不指定Provide名称的情况下,你需要使用相同的名字来定义和接收数据

    1.2.2、通过相同的变量别名绑定

    @Provide('key') 和 @Consume('key') key需要保持一致

    @Provide('aa') money:number = 1000 // Provide跨组件提供数据,实现双向绑定,爷爷提供数据
    @Consume('aa')  mon:number // Consume跨组件接收数据,实现双向绑定,Consume的状态变量不需要初始值
    

    ArkTS所有内容都不支持深层数据(包过深层组件)更新 UI渲染

    相关文章

      网友评论

          本文标题:组件状态共享

          本文链接:https://www.haomeiwen.com/subject/hipeodtx.html