目錄
前言
當我們學會寫一些組件以後,就需要來了解一下一個組件從加載到渲染的整個生命週期,以此來知道我們可以在什麼點對組件進行優化。
關於 ComponentBase
這是所有組件的基類,這是一個抽象類。一般情況下,組件需要繼承這個基類。
下面是 ComponentBase
的內容:
生命週期
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 重新計算組件的渲染樹,然後執行 OnAfterRender
和OnAfterRenderAsync
方法。
同樣地,和 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渲染請求一個重新渲染,然後將觸發 OnAfterRender
和OnAfterRenderAsync
。
Dispose
儘管嚴格來說這不是 ComponentBase
的生命週期方法之一,但如果一個組件實現了 IDisposable
,那麼 Blazor 將在組件從父組件的呈現樹中移除後執行Dispose
方法。
要實現 IDisposable
,我們需要在 razor 文件中添加 @implements IDisposable
。
@implements IDisposable
<h1>一個銷燬組件</h1>
@code {
void IDisposable.Dispose()
{
// Code here
}
}
總結
這一次我們對組件的生命週期有了更深一層次的理解,這對我們編寫組件時非常有幫助的,不僅可以加強組件渲染的效率,同時也對於組件報錯後的原因有了更進一步的排查方法。