HarmonyOS Learning Road Ark Development Framework – ArkTS-Sprache lernen (Grundlegende Grammatik 3)

Lebenszyklus von Seiten und benutzerdefinierten Komponenten

Bevor Sie beginnen, klären Sie die Beziehung zwischen benutzerdefinierten Komponenten und Seiten:

  • Benutzerdefinierte Komponenten: Von @Component dekorierte UI- Einheiten können mehrere Systemkomponenten kombinieren, um eine Wiederverwendung der UI zu erreichen .
  • Seite: die UI- Seite der Anwendung. Es kann aus einer oder mehreren benutzerdefinierten Komponenten bestehen. Die mit @Entry dekorierte benutzerdefinierte Komponente ist die Einstiegskomponente der Seite, also der Stammknoten der Seite. Eine Seite kann nur einen @Entry haben . Nur mit @Entry dekorierte Komponenten können den Lebenszyklus der Seite aufrufen.

Der Seitenlebenszyklus, also der von @Entry dekorierte Komponentenlebenszyklus , bietet die folgenden Lebenszyklusschnittstellen:

  • onPageShow : Wird jedes Mal ausgelöst, wenn die Seite angezeigt wird.
  • onPageHide : Wird jedes Mal ausgelöst, wenn die Seite ausgeblendet wird.
  • onBackPress : Wird ausgelöst, wenn der Benutzer auf die Zurück-Schaltfläche tippt.

Der Komponentenlebenszyklus, dh der Lebenszyklus benutzerdefinierter Komponenten, der im Allgemeinen mit @Component dekoriert ist, bietet die folgenden Lebenszyklusschnittstellen:

  • aboutToAppear : Diese Schnittstelle wird zurückgerufen, wenn die Komponente angezeigt wird. Der spezifische Zeitpunkt besteht darin, nach dem Erstellen einer neuen Instanz der benutzerdefinierten Komponente und vor der Ausführung ihrer build()- Funktion auszuführen.
  • aboutToDisappear : Wird ausgeführt, wenn die benutzerdefinierte Komponente zerstört werden soll.

Der Lebenszyklusprozess ist in der folgenden Abbildung dargestellt. Sie zeigt den Lebenszyklus der von @Entry dekorierten Komponente (Homepage).

 

Der Erstellungs- und Rendering-Prozess benutzerdefinierter Komponenten

  1. Erstellung benutzerdefinierter Komponenten: Instanzen benutzerdefinierter Komponenten werden vom ArkUI-Framework erstellt.
  2. Initialisieren Sie die Mitgliedsvariablen der benutzerdefinierten Komponente: Initialisieren Sie die Mitgliedsvariablen der benutzerdefinierten Komponente, indem Sie Parameter über lokale Standardwerte oder Konstruktoren übergeben. Die Initialisierungsreihenfolge ist die Definitionsreihenfolge der Mitgliedsvariablen.
  3. Wenn der Entwickler aboutToAppear definiert, führen Sie die Methode aboutToAppear aus.
  4. Führen Sie beim ersten Rendern die Build-Methode aus, um die Systemkomponente zu rendern, und erstellen Sie eine Instanz der benutzerdefinierten Komponente, wenn eine benutzerdefinierte Unterkomponente vorhanden ist. Während der Ausführung der Funktion build() beobachtet das Framework den Lesestatus jeder Zustandsvariablen und speichert zwei Zuordnungen:
  • Zustandsvariablen -> UI-Komponenten (einschließlich ForEach und if).
  • UI-Komponente -> Die Update-Funktion dieser Komponente, also eine Lambda-Methode, erstellt als Teilmenge der build()-Funktion die entsprechende UI-Komponente und führt ihre Eigenschaftsmethode aus, wie unten gezeigt.
build() {
  ...
  this.observeComponentCreation(() => {
    Button.create();
  })

  this.observeComponentCreation(() => {
    Text.create();
  })
  ...
}

Wenn die Anwendung im Hintergrund gestartet wird, wird der Anwendungsprozess zu diesem Zeitpunkt nicht zerstört, sodass nur onPageShow ausgeführt werden muss.

Benutzerdefinierte Komponenten werden neu gerendert

Wenn der Ereignishandler ausgelöst wird (z. B. wird ein Klickereignis festgelegt, d. h. das Klickereignis wird ausgelöst), ändert sich die Statusvariable oder die Eigenschaft in LocalStorage/AppStorage ändert sich und führt dazu, dass die gebundene Statusvariable ihren Wert ändert:

  1. Das Framework hat eine Änderung festgestellt und wird ein erneutes Rendern einleiten.
  2. Gemäß den beiden vom Framework gehaltenen Karten (Schritt 4 im Erstellungs- und Rendering-Prozess benutzerdefinierter Komponenten) kann das Framework wissen, welche UI-Komponenten von der Statusvariablen verwaltet werden und welche Aktualisierungsfunktionen diesen UI-Komponenten entsprechen. Führen Sie die Update-Funktion dieser UI-Komponenten aus, um Updates zu minimieren.

Löschen benutzerdefinierter Komponenten

Wenn sich der Zweig der if-Komponente ändert oder sich die Anzahl der Arrays in der Darstellung der ForEach-Schleife ändert, wird die Komponente gelöscht:

  1. Bevor die Komponente gelöscht wird, wird ihre Lebenszyklusfunktion aboutToDisappear aufgerufen und markiert den zu zerstörenden Knoten. Der Knotenlöschmechanismus von ArkUI ist: Der Back-End-Knoten wird direkt aus dem Komponentenbaum entfernt, der Back-End-Knoten wird zerstört und der Front-End-Knoten wird dereferenziert. Wenn der Front-End-Knoten nicht mehr referenziert wird, wird er von der virtuellen JS-Maschine als Müll gesammelt.
  2. Die benutzerdefinierte Komponente und ihre Variablen werden gelöscht, und wenn sie über synchronisierte Variablen wie @Link, @Prop, @StorageLink verfügt, wird die Registrierung bei der Synchronisierungsquelle aufgehoben.

Es wird nicht empfohlen, asynchrones Warten in aboutToDisappear des Lebenszyklus zu verwenden. Wenn in aboutToDisappear des Lebenszyklus eine asynchrone Operation (Promise- oder Rückrufmethode) verwendet wird, bleibt die benutzerdefinierte Komponente im Abschluss von Promise erhalten, bis die Rückrufmethode ausgeführt wird. Dieses Verhalten verhindert die Speicherbereinigung der benutzerdefinierten Komponente.

Das folgende Beispiel zeigt, wann der Lebenszyklus aufgerufen wird:

// Index.ets
import router from '@ohos.router';

@Entry
@Component
struct MyComponent {
  @State showChild: boolean = true;

  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageShow() {
    console.info('Index onPageShow');
  }
  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onPageHide() {
    console.info('Index onPageHide');
  }

  // 只有被@Entry装饰的组件才可以调用页面的生命周期
  onBackPress() {
    console.info('Index onBackPress');
  }

  // 组件生命周期
  aboutToAppear() {
    console.info('MyComponent aboutToAppear');
  }

  // 组件生命周期
  aboutToDisappear() {
    console.info('MyComponent aboutToDisappear');
  }

  build() {
    Column() {
      // this.showChild为true,创建Child子组件,执行Child aboutToAppear
      if (this.showChild) {
        Child()
      }
      // this.showChild为false,删除Child子组件,执行Child aboutToDisappear
      Button('create or delete Child').onClick(() => {
        this.showChild = false;
      })
      // push到Page2页面,执行onPageHide
      Button('push to next page')
        .onClick(() => {
          router.pushUrl({ url: 'pages/Page2' });
        })
    }

  }
}

@Component
struct Child {
  @State title: string = 'Hello World';
  // 组件生命周期
  aboutToDisappear() {
    console.info('[lifeCycle] Child aboutToDisappear')
  }
  // 组件生命周期
  aboutToAppear() {
    console.info('[lifeCycle] Child aboutToAppear')
  }

  build() {
    Text(this.title).fontSize(50).onClick(() => {
      this.title = 'Hello ArkUI';
    })
  }
}

Im obigen Beispiel enthält die Indexseite zwei benutzerdefinierte Komponenten, eine ist MyComponent, dekoriert mit @Entry, die auch die Einstiegskomponente der Seite ist, also der Stammknoten der Seite; die andere ist Child, eine Unterkomponente von MyComponent. Nur die mit @Entry dekorierten Knoten können Auswirkungen auf die Lebenszyklusmethode der Seite haben, daher wird die Seitenlebenszyklusfunktion der aktuellen Indexseite in MyComponent deklariert. MyComponent und seine untergeordnete Komponente Child deklarieren auch die Lebenszyklusfunktion der Komponente.

  • Der Initialisierungsprozess des Kaltstarts der Anwendung ist: MyComponent aboutToAppear -> MyComponent build -> Child aboutToAppear -> Child build -> Ausführung des Child-Builds abgeschlossen -> MyComponent-Build-Ausführung abgeschlossen -> Index onPageShow.
  • Klicken Sie auf „Kind löschen“. Das an this.showChild gebundene if wird falsch. Löschen Sie die untergeordnete Komponente und die Methode „Child aboutToDisappear“ wird ausgeführt.
  • Klicken Sie auf „Zur nächsten Seite drücken“, rufen Sie die Schnittstelle router.pushUrl auf, springen Sie zu einer anderen Seite, blenden Sie die aktuelle Indexseite aus und führen Sie den Seitenlebenszyklus Index onPageHide aus. Hier wird die Schnittstelle router.pushUrl aufgerufen, und die Indexseite wird ausgeblendet und nicht zerstört, sodass nur onPageHide aufgerufen wird. Nachdem Sie zur neuen Seite gesprungen sind, führen Sie den Prozess zur Initialisierung des Lebenszyklus der neuen Seite aus.
  • Wenn router.replaceUrl aufgerufen wird, wird die aktuelle Indexseite zerstört und der ausgeführte Lebenszyklusprozess wird zu: Index onPageHide -> MyComponent aboutToDisappear -> Child aboutToDisappear. Wie oben erwähnt, besteht die Zerstörung einer Komponente darin, den Unterbaum direkt aus dem Komponentenbaum zu entfernen. Rufen Sie also zuerst aboutToDisappear der übergeordneten Komponente auf, rufen Sie dann aboutToDisAppear der untergeordneten Komponente auf und führen Sie dann den Lebenszyklusprozess der Initialisierung einer neuen Seite aus.
  • Klicken Sie auf die Schaltfläche „Zurück“, um den Seitenlebenszyklus-Index bei BackPress auszulösen. Wenn die Anwendung minimiert wird oder in den Hintergrund tritt, wird Index onPageHide ausgelöst. In diesen beiden Zuständen wurde die Anwendung nicht zerstört, sodass aboutToDisappear der Komponente nicht ausgeführt wird. Die Anwendung kehrt in den Vordergrund zurück und führt Index onPageShow aus.
  • Beenden Sie die Anwendung und führen Sie Index onPageHide --> MyComponent aboutToDisappear --> Child aboutToDisappear aus.

@Builder-Dekorator: benutzerdefinierte Build-Funktion

In den vorherigen Kapiteln wurde erläutert, wie eine benutzerdefinierte Komponente erstellt wird. Die interne UI-Struktur der benutzerdefinierten Komponente ist festgelegt und es erfolgt nur eine Datenübertragung mit dem Benutzer. ArkUI bietet außerdem einen einfacheren Wiederverwendungsmechanismus für UI-Elemente @Builder. Die von @Builder dekorierte Funktion folgt den Syntaxregeln der build()-Funktion. Entwickler können die wiederverwendeten UI-Elemente in eine Methode abstrahieren und diese in der Build-Methode aufrufen.

Zur Vereinfachung der Sprache werden mit @Builder dekorierte Funktionen auch als „benutzerdefinierte Build-Funktionen“ bezeichnet.

Anweisungen für Dekorateure

Benutzerdefinierte Build-Funktionen in benutzerdefinierten Komponenten

Definierte Syntax:

@Builder myBuilderFunction({ ... })

Anweisungen:

this.myBuilderFunction({ ... })
  • Ermöglicht das Definieren einer oder mehrerer benutzerdefinierter Build-Funktionen innerhalb einer benutzerdefinierten Komponente, die als private Mitgliedsfunktionen eines speziellen Typs dieser Komponente gelten.
  • Die benutzerdefinierte Build-Funktion kann in der Build-Methode der Komponente und anderen benutzerdefinierten Build-Funktionen aufgerufen werden, darf jedoch nicht außerhalb der Komponente aufgerufen werden.
  • Im benutzerdefinierten Funktionskörper bezieht sich dies auf die aktuelle Komponente, und auf die Zustandsvariablen der Komponente kann in der benutzerdefinierten Konstruktionsfunktion zugegriffen werden. Es wird empfohlen, hierüber auf die Zustandsvariablen benutzerdefinierter Komponenten zuzugreifen, anstatt Parameter zu übergeben.

Globaler benutzerdefinierter Konstruktor

Definierte Syntax:

@Builder function MyGlobalBuilderFunction({ ... })

Anweisungen:

MyGlobalBuilderFunction()
  • Globale benutzerdefinierte Build-Funktionen können von der gesamten Anwendung abgerufen werden. Die Methoden this und bind sind nicht zulässig.
  • Wenn keine Komponentenstatusänderungen beteiligt sind, wird empfohlen, eine globale benutzerdefinierte Build-Methode zu verwenden.

Parameterübergaberegeln

Es gibt zwei Arten der Parameterübergabe für benutzerdefinierte Konstruktoren: Übergabe als Wert und Übergabe als Referenz, die beide den folgenden Regeln entsprechen müssen:

  • Der Typ des Parameters muss mit dem deklarierten Typ des Parameters übereinstimmen. Undefiniert , null und Ausdrücke , die undefiniert und null zurückgeben, sind nicht zulässig.
  • Innerhalb eines benutzerdefinierten Konstruktors dürfen sich Parameterwerte nicht ändern. Wenn Sie den Parameterwert ändern und synchron zum Aufrufpunkt zurückrufen müssen, wird die Verwendung von @Link empfohlen .
  • Die UI- Syntax in @Builder folgt den UI- Syntaxregeln.

Übergeben Sie Parameter als Referenz

Bei der Übergabe von Parametern per Referenz können die übergebenen Parameter Statusvariablen sein, und die Änderung der Statusvariablen führt zu einer Aktualisierung der Benutzeroberfläche in der @Builder-Methode. ArkUI bietet $$ als Paradigma für die Übergabe von Parametern per Referenz.

ABuilder( $$ : { paramA1: string, paramB1 : string } );
@Builder function ABuilder($$: { paramA1: string }) {
  Row() {
    Text(`UseStateVarByReference: ${$$.paramA1} `)
  }
}
@Entry
@Component
struct Parent {
  @State label: string = 'Hello';
  build() {
    Column() {
      // 在Parent组件中调用ABuilder的时候,将this.label引用传递给ABuilder
      ABuilder({ paramA1: this.label })
      Button('Click me').onClick(() => {
        // 点击“Click me”后,UI从“Hello”刷新为“ArkUI”
        this.label = 'ArkUI';
      })
    }
  }
}

Übergeben Sie Parameter nach Wert

Mit @Builder dekorierte Funktionen werden standardmäßig als Wert übergeben. Wenn der übergebene Parameter eine Statusvariable ist, führt die Änderung der Statusvariablen nicht zu einer Aktualisierung der Benutzeroberfläche in der @Builder-Methode. Bei der Verwendung von Zustandsvariablen wird daher empfohlen, die Referenzübergabe zu verwenden.

@Builder function ABuilder(paramA1: string) {
  Row() {
    Text(`UseStateVarByValue: ${paramA1} `)
  }
}
@Entry
@Component
struct Parent {
  label: string = 'Hello';
  build() {
    Column() {
      ABuilder(this.label)
    }
  }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_47094733/article/details/131758695
Recomendado
Clasificación