Blazor —— 深入講解組件的生命週期

前言

當我們學會寫一些組件以後,就需要來了解一下一個組件從加載到渲染的整個生命週期,以此來知道我們可以在什麼點對組件進行優化。

關於 ComponentBase

這是所有組件的基類,這是一個抽象類。一般情況下,組件需要繼承這個基類。

下面是 ComponentBase 的內容:
ComponentBase

生命週期

Blazor 組件定義了一系列的虛方法,這樣我們可以根據需要來重寫裏面的邏輯,以便處理我們自己的邏輯。

我們通過一張圖能更直觀的看到他們的運行順序:

Blazor 生命週期

SetParameterAsync

這個方法在組件運行後執行。參數們,也就是被標記了 Parameter 特性的參數在被設置以後,通過該方法的 ParameterView 參數傳入進來。但是,標記了 [Parameter] 的參數這時還未得到從外面組件的賦值的結果。

示例代碼:

[Parameter] public int Count { get; set; }

public override async Task SetParametersAsync(ParameterView parameters)
{
    Console.WriteLine("Count的值是:{0}", Count);
    var value= parameters.GetValueOrDefault<int>(nameof(Count));
    Console.WriteLine("value的值是:{0}", value);
    await base.SetParametersAsync(parameters);
}
<Lifecycle Count="10"/>

在這裏插入圖片描述
這個時候的 Count 參數的值是處於未被賦值的狀態。因此,通過 parameters.GetValueOrDefault 來獲取某一個參數的值。

OnInitialized / OnInitializedAsync

沒有 Async 後綴的是異步方法,但結果都是一樣的。但是執行順序是:OnInitialized -> OnIntializedAsync

當經過了剛纔的 SetParametersAsync 方法之後,就會立即執行這個方法,表示組件已經初始化完成。這裏我們可以得到所有的被標記過 [Parameter] 參數的值。

Tips:這個時候界面是還沒有開始被渲染,界面是空白狀態,瀏覽器會有一個旋轉圖標,表示加載中,所以儘量避免在這一步編寫長時間操作的代碼,比如查詢數據庫,或者請求別的服務。

當頁面通過超鏈接對本頁面的組件進行跳轉,則不會執行 OnInitialized 方法:
在這裏插入圖片描述

OnParametersSet / OnParametersSetAsync

執行順序依然是先同步後異步,即 OnParametersSet -> OnParametersSetAsync

這是組件生命週期中可能被重複調用的第一對方法。如果組件的[參數]屬性都沒有改變,那麼組件將簡單地閒置,直到它最終被銷燬。但是,如果其父HTML標記中的任何參數被更改,那麼這些方法將在組件狀態更新後觸發。這將導致 Blazor 重新計算組件的渲染樹,然後執行 OnAfterRenderOnAfterRenderAsync 方法。

同樣地,和 OnInitialized 方法一樣,如果是同一組頁面的組件,則不會執行 OnParametersSet 方法。參見上面的例子。

舉個例子:

<Lifecycle Count="10" Name="@Name"/>
<input type="text" @bind-value="Name" />
<br />
@Name
@code{
    public string Name { get; set; }
}

在這裏插入圖片描述
父組件的 Name 是一個被文本框進行雙向綁定的變量,卻又給組件的 Name 參數進行了賦值,因此當文本框進行了改變後,Name 變量發生了變化,因此被組件賦值的 Name 參數也發生了變化,然後 OnParametersSet 方法被執行了。

OnAfterRender / OnAfterRenderAsync

執行順序爲 OnAfterRender -> OnAfterRenderAsync

該方法會在渲染樹工作完成後執行,即頁面渲染結束。但該方法被執行一般會有以下情況:

  • 組件的[Parameter] 屬性在父組件的HTML標記中被改變
  • 用戶與組件進行了交互(例如鼠標點擊)
  • 組件執行它的 StateHasChanged 方法來調用一個重新呈現。

該方法會有一個布爾值參數 firstRender,該參數只有在方法第一次在當前組件上被調用時才爲 true,此後它將始終爲 false

爲了演示,我增加了一個按鈕功能。

在這裏插入圖片描述

StateHasChanged

此方法不符合生命週期方法的資格,但它確實觸發了組件生命週期中的另一個方法。在默認情況下,Blazor會檢查它的狀態是否在某些交互之後發生了改變(比如點擊按鈕)。

有時 Blazor 無法意識到狀態的變化,例如何時被計時器觸發。這時你需要手動調用 StateHasChanged 來通知 Blazor 某些參數已經被更改。表示向 Blazor渲染請求一個重新渲染,然後將觸發 OnAfterRenderOnAfterRenderAsync

Dispose

儘管嚴格來說這不是 ComponentBase 的生命週期方法之一,但如果一個組件實現了 IDisposable,那麼 Blazor 將在組件從父組件的呈現樹中移除後執行Dispose 方法。

要實現 IDisposable,我們需要在 razor 文件中添加 @implements IDisposable

@implements IDisposable
<h1>一個銷燬組件</h1>

@code {
	void IDisposable.Dispose()
	{
		// Code here
	}
}

總結

這一次我們對組件的生命週期有了更深一層次的理解,這對我們編寫組件時非常有幫助的,不僅可以加強組件渲染的效率,同時也對於組件報錯後的原因有了更進一步的排查方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章