<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      概述


      現階段狀態管理V2版本還在試用階段,但是切實解決了很多在項目中使用V1導致的痛點問題,比如:

      • 同一數據被多視圖代理時,無法同步數據修改。
      • 無法做到深度觀測和深度監聽。
      • 更新對象中某個數據時,會導致整個對象屬性都刷新,導致程序運行緩慢。

      狀態管理V2版 裝飾器總覽

      • @ObservedV2:裝飾class,使得裝飾的class具有深度監聽的能力。
      • @Trace:只能在@ObservedV2裝飾的class中使用,被裝飾的屬性具有深度觀測的能力。
      • @ComponentV2:裝飾頁面或者自定義組件。確定struct中可以使用V2版的裝飾器。
      • @Local:裝飾的變量為當前組件的內部狀態,無法從外部初始化。
      • @Param:裝飾的變量為組件的輸入,可以接受從外部傳入初始化并同步。
      • @Once:裝飾的變量僅初始化時同步一次,需要與@Param一起使用。
      • @Event:裝飾方法類型,作為組件輸出,可以通過該方法影響父組件中變量。
      • @Monitor:裝飾器用于@ComponentV2裝飾的自定義組件或@ObservedV2裝飾的類中,能夠對狀態變量進行深度監聽。
      • @Provider和@Consumer:用于跨組件層級雙向同步。
      • @Computed:計算屬性,在被計算的值變化的時候,只會計算一次。主要應用于解決UI多次重用該屬性從而重復計算導致的性能問題
      • !!語法:雙向綁定語法糖。

      class的深入監測

      使用@ObservedV2和@Trace兩種裝飾器,實現對屬性修改的觀測能力。具有以下特點:

      • 被@Trace裝飾器裝飾的屬性變化時,僅會通知屬性關聯的組件進行刷新。
      • @ObservedV2的類實例目前不支持使用JSON.stringify進行序列化。

      @Trace可裝飾的變量

      class中成員屬性。屬性的類型可以為number、string、boolean、class、Array、Date、Map、Set等類型。

      @Trace可觀測API變化

      【HarmonyOS Next】狀態管理V2版本使用詳解_初始化

      使用

      新建三個class,Father,Son,Son2。

      • Son類被@ObservedV2裝飾器裝飾,age屬性被@Trace裝飾器裝飾。因此,age屬性的修改會引起UI更新。
      • Father類沒有被@ObservedV2裝飾器修飾。
      • Son2類繼承Son類,有一個沒有被@Trace裝飾器裝飾的Telephone屬性。
      @Entry
      @ComponentV2
      struct ObservedPage {
        father: Father = new Father();
        son2: Son2 = new Son2();
      
        build() {
          Column({ space: 10 }) {
            Text(`Father中的son年齡:${this.father.son.age}`)
              .fontSize(30)
              .onClick(() => {
                this.father.son.age++;
              })
      
            Text(`Son2年齡:${this.son2.age}`)
              .fontSize(30)
              .onClick(() => {
                this.son2.age++;
              })
      
            Text(`Son2電話:${this.son2.Telephone}`)
              .fontSize(30)
              .onClick(() => {
                this.son2.Telephone = "12348";
              })
          }
          .height('100%')
          .width('100%')
          .alignItems(HorizontalAlign.Start)
          .margin({ left: 10 })
        }
      }
      
      @ObservedV2
      class Son {
        @Trace age: number = 100;
      }
      
      class Father {
        son: Son = new Son();
      }
      
      class Son2 extends Son {
        Telephone: string = "12306";
      }
      • 1.
      • 2.
      • 3.
      • 4.
      • 5.
      • 6.
      • 7.
      • 8.
      • 9.
      • 10.
      • 11.
      • 12.
      • 13.
      • 14.
      • 15.
      • 16.
      • 17.
      • 18.
      • 19.
      • 20.
      • 21.
      • 22.
      • 23.
      • 24.
      • 25.
      • 26.
      • 27.
      • 28.
      • 29.
      • 30.
      • 31.
      • 32.
      • 33.
      • 34.
      • 35.
      • 36.
      • 37.
      • 38.
      • 39.
      • 40.
      • 41.
      • 42.
      • 43.
      • 44.
      • 45.

      實現效果如下:

      【HarmonyOS Next】狀態管理V2版本使用詳解_Text_02

      自定義組件

      使用@ComponentV2裝飾器結合@Local、@Param、@Once、@Event、@Provider、@Consumer等裝飾器,實現自定義組件的狀態觀測。

      使用時需要注意的點是:復雜類型常量重復賦值給狀態變量時,會重復觸發刷新,可能導致冗余刷新,因此,為了避免這種不必要的賦值和刷新,可以使用UIUtils.getTarget()獲取原始對象提前進行新舊值的判斷,當兩者相同時不執行賦值。

      @Local

      使用@Local裝飾對象,可以達到觀測對象本身變化的效果。

      具有以下特點:

      • 被@Local裝飾的變量無法從外部初始化,因此必須在組件內部進行初始化。
      • @Local支持觀測number、boolean、string、Object、class等基本類型以及Array、Set、Map、Date等內嵌類型。
      • @Local支持null、undefined以及聯合類型。
      • 當裝飾的變量類型是內置類型時,可以觀察到變量整體賦值以及通過API調用帶來的變化。

      代碼實現

      新建一個class對象Info,其中name屬性被@Trace裝飾器裝飾,age屬性沒有被裝飾

      @Entry
      @ComponentV2
      struct ComponentPage {
        info1: Info = new Info("Tom", 25);
        @Local info2: Info = new Info("Tom", 25);
      
        build() {
          Column({ space: 10 }) {
            Text(`info1: ${this.info1.name}-${this.info1.age}`).fontSize(30) // Text1
            Text(`info2: ${this.info2.name}-${this.info2.age}`).fontSize(30) // Text2
            Button("change info1&info2")
              .onClick(() => {
                this.info1 = new Info("Lucy", 18); // Text1不會刷新
                this.info2 = new Info("Lucy", 18); // Text2會刷新
              })
            Button("修改info2的名字")
              .onClick(() => {
                this.info2.name = "zzx" // Text2會刷新
              })
            Button("修改info2的年齡")
              .onClick(() => {
                this.info2.age++; // Text2不會刷新
              })
          }
          .width("100%")
          .height("100%")
        }
      }
      
      @ObservedV2
      class Info {
        @Trace name: string;
        age: number;
      
        constructor(name: string, age: number) {
          this.name = name;
          this.age = age;
        }
      }
      • 1.
      • 2.
      • 3.
      • 4.
      • 5.
      • 6.
      • 7.
      • 8.
      • 9.
      • 10.
      • 11.
      • 12.
      • 13.
      • 14.
      • 15.
      • 16.
      • 17.
      • 18.
      • 19.
      • 20.
      • 21.
      • 22.
      • 23.
      • 24.
      • 25.
      • 26.
      • 27.
      • 28.
      • 29.
      • 30.
      • 31.
      • 32.
      • 33.
      • 34.
      • 35.
      • 36.
      • 37.
      • 38.
      • 39.

      實現效果如下:

      • 點擊“change info1&info2”按鈕,Text1不會刷新,Text2會刷新。
      • 點擊“修改info2的名字” 按鈕,Text2會刷新。
      • 點擊“修改info2的年齡” 按鈕,Text2不會刷新。

      【HarmonyOS Next】狀態管理V2版本使用詳解_Text_03

      @Param

      具有以下特點:

      • @Param裝飾的變量支持本地初始化,但是不允許在組件內部直接修改變量本身。
      • 被@Param裝飾的變量能夠在初始化自定義組件時從外部傳入,當數據源也是狀態變量時,數據源的修改會同步給@Param。
      • @Param可以接受任意類型的數據源,包括普通變量、狀態變量、常量、函數返回值等。
      • @Param裝飾的變量變化時,會刷新該變量關聯的組件。
      • @Param支持觀測number、boolean、string、Object、class等基本類型以及Array、Set、Map、Date等內嵌類型。
      • 當裝飾簡單類型時,對變量的整體改變能夠觀測到;當裝飾對象類型時,僅能觀測對象整體的改變;當裝飾數組類型時,能觀測到數組整體以及數組元素項的改變;當裝飾Array、Set、Map、Date等內嵌類型時,可以觀測到通過API調用帶來的變化。
      • @Param支持null、undefined以及聯合類型。

      【HarmonyOS Next】狀態管理V2版本使用詳解_Text_04

      代碼實現

      @Entry
      @ComponentV2
      struct ParamPage {
        @Local infoList: ParamInfo[] =
          [new ParamInfo("Alice", 8, 0, 0), new ParamInfo("Barry", 10, 1, 20), new ParamInfo("Cindy", 18, 24, 40)];
      
        build() {
          Column({ space: 10 }) {
            ForEach(this.infoList, (info: ParamInfo) => {
              MiddleComponent({ info: info })
            })
            Button("修改")
              .onClick(() => {
                this.infoList[0] = new ParamInfo("Atom", 40, 27, 90);
                this.infoList[1].name = "Bob";
                this.infoList[2].region = new Region(7, 9);
              })
          }
          .margin({ left: 10 })
          .width("100%")
          .height("100%")
          .alignItems(HorizontalAlign.Start)
        }
      }
      
      @ComponentV2
      struct MiddleComponent {
        @Param info: ParamInfo = new ParamInfo("0", 0, 0, 0);
      
        build() {
          Column({ space: 10 }) {
            Text(`name: ${this.info.name}`).fontSize(30)
            Text(`age: ${this.info.age}`).fontSize(30)
            SubComponent({ region: this.info.region })
          }
          .alignItems(HorizontalAlign.Start)
        }
      }
      
      @ComponentV2
      struct SubComponent {
        @Param region: Region = new Region(0, 0);
      
        build() {
          Column() {
            Text(`region: ${this.region.x}-${this.region.y}`).fontSize(30)
          }
        }
      }
      
      @ObservedV2
      class Region {
        @Trace x: number;
        @Trace y: number;
      
        constructor(x: number, y: number) {
          this.x = x;
          this.y = y;
        }
      }
      
      @ObservedV2
      class ParamInfo {
        @Trace name: string;
        @Trace age: number;
        @Trace region: Region;
      
        constructor(name: string, age: number, x: number, y: number) {
          this.name = name;
          this.age = age;
          this.region = new Region(x, y);
        }
      }
      • 1.
      • 2.
      • 3.
      • 4.
      • 5.
      • 6.
      • 7.
      • 8.
      • 9.
      • 10.
      • 11.
      • 12.
      • 13.
      • 14.
      • 15.
      • 16.
      • 17.
      • 18.
      • 19.
      • 20.
      • 21.
      • 22.
      • 23.
      • 24.
      • 25.
      • 26.
      • 27.
      • 28.
      • 29.
      • 30.
      • 31.
      • 32.
      • 33.
      • 34.
      • 35.
      • 36.
      • 37.
      • 38.
      • 39.
      • 40.
      • 41.
      • 42.
      • 43.
      • 44.
      • 45.
      • 46.
      • 47.
      • 48.
      • 49.
      • 50.
      • 51.
      • 52.
      • 53.
      • 54.
      • 55.
      • 56.
      • 57.
      • 58.
      • 59.
      • 60.
      • 61.
      • 62.
      • 63.
      • 64.
      • 65.
      • 66.
      • 67.
      • 68.
      • 69.
      • 70.
      • 71.
      • 72.
      • 73.

      實現效果:

      【HarmonyOS Next】狀態管理V2版本使用詳解_Text_05

      @Once

      可以對@Param裝飾器的能力進行修改,具有以下的特點:

      • @Once必須搭配@Param使用,單獨使用或搭配其他裝飾器使用都是不允許的。
      • @Once不影響@Param的觀測能力,僅針對數據源的變化做攔截。
      • @Once與@Param搭配使用時,可以在本地修改@Param變量的值。

      @Event

      使用@Event裝飾器裝飾回調方法,可以實現子組件對父組件傳遞的@Param裝飾的變量進行修改。類似子組件定義了一個委托函數,然后在父組件初始化的時候,對子組件的委托函數進行定義,子組件可以使用委托函數來實現想要的效果。

      使用場景

      更改父組件中的變量

      @Entry
      @ComponentV2
      struct EventPage {
        @Local title: string = "Titile One";
        @Local fontColor: Color = Color.Red;
      
        build() {
          Column() {
            Child({
              title: this.title,
              fontColor: this.fontColor,
              changeFactory: (type: number) => {
                if (type == 1) {
                  this.title = "Title One";
                  this.fontColor = Color.Red;
                } else if (type == 2) {
                  this.title = "Title Two";
                  this.fontColor = Color.Green;
                }
              }
            })
          }
          .width("100%")
          .height("100%")
        }
      }
      
      @ComponentV2
      struct Child {
        @Param title: string = '';
        @Param fontColor: Color = Color.Black;
        @Event changeFactory: (x: number) => void = (x: number) => {
        };
      
        build() {
          Column({ space: 10 }) {
            Text(`${this.title}`)
            Button("change to Title Two")
              .onClick(() => {
                this.changeFactory(2);
              })
            Button("change to Title One")
              .onClick(() => {
                this.changeFactory(1);
              })
          }
        }
      }
      • 1.
      • 2.
      • 3.
      • 4.
      • 5.
      • 6.
      • 7.
      • 8.
      • 9.
      • 10.
      • 11.
      • 12.
      • 13.
      • 14.
      • 15.
      • 16.
      • 17.
      • 18.
      • 19.
      • 20.
      • 21.
      • 22.
      • 23.
      • 24.
      • 25.
      • 26.
      • 27.
      • 28.
      • 29.
      • 30.
      • 31.
      • 32.
      • 33.
      • 34.
      • 35.
      • 36.
      • 37.
      • 38.
      • 39.
      • 40.
      • 41.
      • 42.
      • 43.
      • 44.
      • 45.
      • 46.
      • 47.
      • 48.

      實現效果:

      【HarmonyOS Next】狀態管理V2版本使用詳解_初始化_06

      @Provider和@Consumer

      僅能修飾自定義組件內的屬性,不能修飾class的屬性。

      和V1版本中的@Provide和@Consume有異曲同工之妙,主要用于跨組件層級數據雙向同步,但也存在不一樣的能力:

      【HarmonyOS Next】狀態管理V2版本使用詳解_初始化_07

      @Provider語法:

      @Provider(alias?: string) varName : varType = initValue

      • aliasName?: string,別名,缺省時默認為屬性名,向上查找最近的@Provider。

      @Consumer語法:

      @Consumer(alias?: string) varName : varType = initValue

      • aliasName?: string,別名,缺省時默認為屬性名。

      使用場景

      子組件需要修改父組件的內容,可以使用 @Provider和@Consumer來實現。

      @Entry
      @ComponentV2
      struct ProviderPage {
        @Local childX: number = 0;
        @Local childY: number = 1;
        @Provider() onClick1: (x: number, y: number) => void = (x: number, y: number) => {
          this.childX += x;
          this.childY += y;
        }
      
        build() {
          Column({ space: 20 }) {
            Text(`child changed x: ${this.childX}, y: ${this.childY}`).fontSize(30)
            ProviderPageChild()
          }
          .width("100%")
          .height("100%")
        }
      }
      
      @ComponentV2
      struct ProviderPageChild {
        @Consumer() onClick1: (x: number, y: number) => void = (x: number, y: number) => {
        };
      
        build() {
          Button("changed")
            .draggable(true)
            .onClick(() => {
              this.onClick1(1, 1);
            })
        }
      }
      • 1.
      • 2.
      • 3.
      • 4.
      • 5.
      • 6.
      • 7.
      • 8.
      • 9.
      • 10.
      • 11.
      • 12.
      • 13.
      • 14.
      • 15.
      • 16.
      • 17.
      • 18.
      • 19.
      • 20.
      • 21.
      • 22.
      • 23.
      • 24.
      • 25.
      • 26.
      • 27.
      • 28.
      • 29.
      • 30.
      • 31.
      • 32.
      • 33.

      【HarmonyOS Next】狀態管理V2版本使用詳解_ide_08

      @Monitor

      • 用來監聽狀態變量變化,支持在類中與@ObservedV2、@Trace配合使用。
      • 單個@Monitor裝飾器能夠同時監聽多個屬性的變化,當這些屬性在一次事件中共同變化時,只會觸發一次@Monitor的回調方法。
      • @Monitor裝飾器具有深度監聽的能力,能夠監聽嵌套類、多維數組、對象數組中指定項的變化。對于嵌套類、對象數組中成員屬性變化的監聽要求該類被@ObservedV2裝飾且該屬性被@Trace裝飾
      • 在繼承類場景中,可以在父子組件中對同一個屬性分別定義@Monitor進行監聽,當屬性變化時,父子組件中定義的@Monitor回調均會被調用。

      裝飾器參數

      字符串類型的對象屬性名。可同時監聽多個對象屬性,每個屬性以逗號隔開,例如@Monitor("prop1", "prop2")。可監聽深層的屬性變化,如多維數組中的某一個元素,嵌套對象或對象數組中的某一個屬性。

      @Monitor("childX")
        OnChange(monitor: IMonitor) {
          //do something
        }
      • 1.
      • 2.
      • 3.
      • 4.

      IMonitor類型的變量用作@Monitor裝飾方法的參數。

      IMonitor類型參數

      • dirty:Array :保存發生變化的屬性名。
      • value:function:傳入參數為path?: string,返回IMonitorValue類型參數。

      IMonitorValue類型參數

      • before:T:監聽屬性變化之前的值。
      • now:T:監聽屬性變化之后的當前值。
      • path:string:監聽的屬性名。

      使用場景

      新建MonitorInfo類和被@ObservedV2裝飾器裝飾并繼承MonitorInfo類的MonitorInfo2。

      @Entry
      @ComponentV2
      struct MonitorPage {
        @Local info: MonitorInfo = new MonitorInfo("Tom", 25);
        @Local info2: MonitorInfo2 = new MonitorInfo2("zzx", 27, "zhongzx");
      
        @Monitor("info")
        infoChange(monitor: IMonitor) {
          console.log(`MonitorInfo change`);
        }
      
        @Monitor("info.name")
        infoPropertyChange(monitor: IMonitor) {
          console.log(`MonitorInfo name change`);
        }
      
        @Monitor("info2")
        info2Change(monitor: IMonitor) {
          console.log(`MonitorInfo2 change`);
        }
      
        @Monitor("info2.fullname")
        info2PropertyChange(monitor: IMonitor) {
          console.log(`MonitorInfo2 fullname change`);
        }
      
        build() {
          Column({ space: 10 }) {
            Text(`name: ${this.info.name}, age: ${this.info.age}`)
            Text(`name: ${this.info2.name}, age: ${this.info2.age},fullName:${this.info2.fullname}`)
            Button("change info")
              .onClick(() => {
                this.info = new MonitorInfo("Lucy", 18); // 能夠監聽到
              })
            Button("change info.name")
              .onClick(() => {
                this.info.name = "Jack"; // 監聽不到
              })
            Button("change info2")
              .onClick(() => {
                this.info2 = new MonitorInfo2("Lucy", 20, "hl"); // 能夠監聽到
              })
            Button("change info2.fullName")
              .onClick(() => {
                this.info2.fullname = "hhl"; // 能夠監聽到
              })
            Button("change info2.name")
              .onClick(() => {
                this.info2.name = "Jack"; // 監聽不到
              })
          }
          .width("100%")
          .height("100%")
        }
      }
      
      class MonitorInfo {
        name: string;
        age: number;
      
        constructor(name: string, age: number) {
          this.name = name;
          this.age = age;
        }
      }
      
      @ObservedV2
      class MonitorInfo2 extends MonitorInfo {
        @Trace fullname: string = "";
      
        constructor(name: string, age: number, fullName: string) {
          super(name, age);
          this.fullname = fullName;
        }
      }
      • 1.
      • 2.
      • 3.
      • 4.
      • 5.
      • 6.
      • 7.
      • 8.
      • 9.
      • 10.
      • 11.
      • 12.
      • 13.
      • 14.
      • 15.
      • 16.
      • 17.
      • 18.
      • 19.
      • 20.
      • 21.
      • 22.
      • 23.
      • 24.
      • 25.
      • 26.
      • 27.
      • 28.
      • 29.
      • 30.
      • 31.
      • 32.
      • 33.
      • 34.
      • 35.
      • 36.
      • 37.
      • 38.
      • 39.
      • 40.
      • 41.
      • 42.
      • 43.
      • 44.
      • 45.
      • 46.
      • 47.
      • 48.
      • 49.
      • 50.
      • 51.
      • 52.
      • 53.
      • 54.
      • 55.
      • 56.
      • 57.
      • 58.
      • 59.
      • 60.
      • 61.
      • 62.
      • 63.
      • 64.
      • 65.
      • 66.
      • 67.
      • 68.
      • 69.
      • 70.
      • 71.
      • 72.
      • 73.
      • 74.
      • 75.

      實現效果如下:

      • 整體替換的時候,都可以監測到。
      • 沒有使用@ObservedV2和@Trace裝飾器的class屬性修改時無法被監測到。

      【HarmonyOS Next】狀態管理V2版本使用詳解_初始化_09

      【HarmonyOS Next】狀態管理V2版本使用詳解_ide_10

      總結


      簡單講解了主要的V2裝飾器,其中還有一些裝飾在試用的時候出錯了,就沒有把使用方法總結出來。希望可以幫助到大家

      posted on 2024-12-24 11:08  鐘子翔  閱讀(340)  評論(0)    收藏  舉報  來源
      主站蜘蛛池模板: 正在播放酒店约少妇高潮| 国产超碰无码最新上传| 资源新版在线天堂偷自拍| 国产激情视频在线观看首页| 免费a级黄毛片| 亚洲一区二区av偷偷| 午夜av高清在线观看| 波多野结衣一区二区三区高清| 精品人妻伦九区久久69| 亚洲精品第一页中文字幕| 欧美国产精品啪啪| 老司机性色福利精品视频| 亚日韩精品一区二区三区| 久久影院午夜伦手机不四虎卡| 中文字幕国产在线精品| 亚洲高清免费在线观看| 成 人 色 网 站免费观看| 通城县| 国产精品亚洲专区无码破解版| 大香蕉av一区二区三区| 免费超爽大片黄| 人成午夜大片免费视频77777| 国产日女人视频在线观看| 国产成人免费观看在线视频 | 国内少妇人妻偷人精品视频| 久9视频这里只有精品| 国产精品视频一区不卡| 亚洲综合色婷婷中文字幕| 曰韩亚洲AV人人夜夜澡人人爽| 奇米四色7777中文字幕| 亚洲成a人无码av波多野| 四川丰满少妇无套内谢| 精品国产免费第一区二区三区 | 亚洲精品国产老熟女久久| 国产V日韩V亚洲欧美久久| 国产精品中文av专线| 人妻少妇久久中文字幕| 国产小视频一区二区三区| 久久精品国产亚洲av天海翼| 少妇人妻av毛片在线看| 日韩激情成人|