美文网首页
组件状态共享2

组件状态共享2

作者: 家乡的蝈蝈 | 来源:发表于2024-01-28 17:47 被阅读0次

    1、组件状态共享2

    1.1、状态共享-状态监听器

    修饰符: entry、component、State、Prop、Link、Provide、Consume
      关注某个状态变量的值是否改变,可以使用 @Watch 为状态变量设置回调函数。
      Watch("回调函数名")中的回调必须在组件中声明,该函数接收一个参数,参数为修改的属性名
    注意:Watch修饰符要写在 State Prop Link Provide Consume的修饰符下面,否则会有问题

    @State
      @Watch('updateMessage') // Watch("回调函数名"),在state后面
      num:number = 0
      updateMessage() {
        promptAction.showToast({message:this.num.toString()})
      }
    

    有了watch 我们就可以随心所欲的搞监听了,比如
    ● 父组件数据变化了, 子组件随机而动
    ● 子组件双向更新了父组件数据,父组件随机而动

     @Provide('aa')
      @Watch('updateMoney')
      money:number = 1000 // Provide跨组件提供数据,实现双向绑定,爷爷提供数据
      updateMoney() {
        promptAction.showToast({message:"钱变了"})
      }
    

    1.2、@Observed和@ObjectLink

      封装的组件没办法做双向更新同步(传入Link修饰的数据必须得是最外层的 State数据,使用for循环最外层就不是state修饰了,即必须是根组件的state数据,不能是循环出来的数据),那么ArtTS支持 Observed和@ObjectLink来实现这个需求
      使用步骤:
    ● 类 class 数据需要定义构造函数,使用 @Observed 修饰这个类
    ● 初始化数据:需要通过初始化构造函数的方式添加(不能使用字面量{}来构建)
    ● 通过 @ObjectLink 关联对象,可以直接修改被关联对象来更新UI

    @Entry
    @Component
    struct ObjectLinkCase {
      @State message: string = 'Hello World'
      @State
      list:FoodObjectClass[] = [new FoodObjectClass({
        order_id: 1,
        food_name: '鱼香肉丝',
        food_price: 18.8,
        food_count: 1
      }), new FoodObjectClass({
        order_id: 2,
        food_name: '粗溜丸子',
        food_price: 26,
        food_count: 2
      }),new FoodObjectClass({
        order_id: 3,
        food_name: '杂粮煎饼',
        food_price: 12,
        food_count: 1
      })]
    
      build() {
        Row() {
          Column({space:20}) {
            ForEach(this.list, (item:FoodObjectClass)=>{
              FoodItem({item:item}) // 传入的item的对象的类被Observed
            })
            BottonCard({myList:$list})
          }
          .width('100%')
        }
        .height('100%')
      }
    }
    
    @Extend(Text)
    function AddTextStyle() {
     .width(40).height(40).borderRadius(20).backgroundColor(Color.Gray)
      .textAlign(TextAlign.Center).fontSize(20)
    }
    
    @Extend(Text)
    function TextStyle() {
      .layoutWeight(1).textAlign(TextAlign.Center).fontSize(20)
    }
    
    @Component
    struct FoodItem {
      @ObjectLink
      item:FoodObjectClass // 使用ObjectLink接收对象,此时父子组件具备双向更新
      build() {
        Row() {
          Text(this.item.food_name).TextStyle()
          Text(this.item.food_price.toFixed(2)).TextStyle()
          Row() {
              Text('-').AddTextStyle()
                .onClick(() => {
                  this.item.food_count--
                })
                .visibility(this.item.food_count > 0 ? Visibility.Visible : Visibility.Hidden)
            Text(this.item.food_count.toString()).TextStyle()
              .visibility(this.item.food_count > 0 ? Visibility.Visible : Visibility.Hidden)
            Text('+').AddTextStyle()
              .onClick(() => {
                this.item.food_count++
              })
          }.layoutWeight(1)
        }
        .height(40)
        .width('100%')
      }
    }
    
    interface FoodInfo { // 接口:1、不能给初始值 2、用接口声明类型
      order_id:number
      food_name:string
      food_price:number
      food_count:number
    }
    
    // observe监听的是class的变化,当class中的某一项值变化,就会触发当前ui的更新
    // 食品类
    @Observed // 使用observe修饰带构造函数的类
    class FoodObjectClass implements FoodInfo {
      // implements代表继承实现的意思,继承接口中的属性
      order_id = 0  // class中的属性必须给初始值,属性类型可以去掉
      food_name:  string = ""
      food_price: number = 0
      food_count: number = 0
      constructor(obj:FoodInfo) {
        this.order_id = obj.order_id
        this.food_name = obj.food_name
        this.food_price = obj.food_price
        this.food_count = obj.food_count
      }
    }
    
    @Component
    struct BottonCard {
      @Link
      myList:FoodObjectClass[]
      build() {
        Button('更改菜品的数量')
          .onClick(() => {
            // map循环数组返回新数组,map中item代表数组中的元素,map会将其中的item组成一个新的数组
            this.myList = this.myList.map(item => {
              item.food_count++
              return item
            })
          })
      }
    }
    

      上述代码中,我们用了interface,interface声明类型不需要给初始值,class声明类型必须给初始值(下一代要求)
    ● 我们使用Class继承实现了interface,并且通过传入的对象将我们Class中的属性进行赋值
    ● 使用了Observed这个装饰器来修饰class,那么只要我们改动class的属性,它就会驱动UI的更新(只是第一层)
      注意: 只有Observed修饰的class才可以被 ObjectLink使用,并且Entry修饰的组件不允许使用ObjectLink

    相关文章

      网友评论

          本文标题:组件状态共享2

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