1.環境
VS2019 16.5.1
.NET Core SDK 3.1.200
Blazor WebAssembly Templates 3.2.0-preview2.20160.5
2.簡介
Blazor的生命周期與React組件的生命周期類似,也分為三個階段:初始化階段、運行中階段和銷毀階段,其相關方法有10個,包括設置參數前、初始化、設置參數之后、組件渲染后以及組件的銷毀,但是這些方法有些是重復的,只不過是同步與異步的區別。本文將介紹Blazor WASM的生命周期。
3.圖解
首先將結果圖呈現,代碼位於第4部分:
Blazor生命周期方法主要包括:
1 | 設置參數前 | SetParametersAsync |
2 | 初始化 | OnInitialized/OnInitializedAsync |
3 | 設置參數后 | OnParametersSet/OnParametersSetAsync |
4 | 組件渲染呈現后 | OnAfterRender/OnAfterRenderAsync |
5 | 判斷是否渲染組件 | ShouldRender |
6 | 組件刪除前 | Dispose |
7 | 通知組件渲染 | StateHasChanged |
在所有生命周期函數中,有以下需要注意的點:
(1)前5種方法的聲明都是virtual,除SetParametersAsync為public外,其他的都是protected。
(2)OnAfterRender/OnAfterRenderAsync方法有一個bool類型的形參firstRender,用於指示是否是第一次渲染(即組件初始化時的渲染)。
(3)同步方法總是先於異步方法執行。
(4)Dispose函數需要通過使用@implements指令實現IDisposable接口來實現。
(5)StateHasChanged無法被重寫,可以被顯示調用,以便強制實現組件刷新(如果ShouldRender返回true,並且Blazor認為需要刷新);當組件狀態更改時不必顯示調用此函數,也可導致組件的重新渲染(如果ShouldRender返回true),因為其已經在ComponentBase內部的處理過程(第一次初始化設置參數時、設置參數后和DOM事件處理等)中被調用。
4.代碼實例
首先使用VS創建一個新Blazor WASM應用程序,其默認帶有一個Count.razor組件,這個組件是示例如何使用事件和更改組件狀態的,可以直接用來示例。
4.1.LifecycleTest組件
為了顯示父組件更改屬性導致組件渲染的這一過程中組件生命周期方法的調用過程,因此需要新建一個組件LifecycleTest.razor,將原來Count.razor組件,的所有代碼都剪切到LifecycleTest.razor中,並為其添加一個組件參數Title,並在頁面組件中顯示:
<h3>LifecycleTest,Title:@Title</h3> [Parameter] public string Title { get; set; }
為了顯示通過調用StateHasChanged方法使組件刷新的過程,在LifecycleTest.razor組件中添加一個新的按鈕“NotifyStateHasChanged”,並為其綁定事件方法:
<button class="btn btn-secondary" @onclick="NotifyStateHasChanged">NotifyStateHasChanged</button> void NotifyStateHasChanged() { Console.WriteLine("NotifyStateHasChanged"); StateHasChanged(); }
此外,為了顯示組件被刪除時Dispose方法的執行過程,需要為組件繼承IDisposable接口,並實現IDisposable的Dispose方法:
public void Dispose() { Console.WriteLine("Dispose"); }
最后,實現所有的生命周期函數,LifecycleTest.razor的所有的代碼如下:
@implements IDisposable <h3>LifecycleTest,Title:@Title</h3> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> <button class="btn btn-secondary" @onclick="NotifyStateHasChanged">NotifyStateHasChanged</button> @code { [Parameter] public string Title { get; set; } private int currentCount = 0; private void IncrementCount() { currentCount++; } void NotifyStateHasChanged() { Console.WriteLine("NotifyStateHasChanged"); StateHasChanged(); } #region 初始化組件 protected override void OnInitialized() { Console.WriteLine("OnInitialized"); base.OnInitialized(); } protected override Task OnInitializedAsync() { Console.WriteLine("OnInitializedAsync"); return base.OnInitializedAsync(); } #endregion /// <summary> /// 設置參數前 /// </summary> /// <param name="parameters"></param> /// <returns></returns> public override Task SetParametersAsync(ParameterView parameters) { Console.WriteLine("SetParametersAsync"); return base.SetParametersAsync(parameters); } #region 設置參數之后 protected override void OnParametersSet() { Console.WriteLine("OnParametersSet"); base.OnParametersSet(); } protected override Task OnParametersSetAsync() { Console.WriteLine("OnParametersSetAsync"); return base.OnParametersSetAsync(); } #endregion #region 組件呈現之后 protected override void OnAfterRender(bool firstRender) { Console.WriteLine($"OnAfterRender, firstRender:{firstRender}"); base.OnAfterRender(firstRender); } protected override Task OnAfterRenderAsync(bool firstRender) { Console.WriteLine($"OnAfterRenderAsync, firstRender:{firstRender}"); return base.OnAfterRenderAsync(firstRender); } #endregion /// <summary> /// 是否渲染組件 /// </summary> /// <returns></returns> protected override bool ShouldRender() { Console.WriteLine("ShouldRender"); return true; } public void Dispose() { Console.WriteLine("Dispose"); } }
4.2.Count.razor頁面
現在,我們在Count.razor中引用LifecycleTest組件,為其參數Title賦值title,並在Count.razor中添加一個按鈕,添加事件ChangeParamter,用於改變title的值。Count.razor的所有代碼如下:
@page "/counter" <button class="btn btn-warning" @onclick="ChangeParamter">ChangeParamter</button> <LifecycleTest Title="@title"></LifecycleTest> @code { string title = "here is the title parameter"; void ChangeParamter() { title = DateTime.Now.ToString("o"); } }
4.3.執行結果
運行本應用程序,進入count頁面,在瀏覽器的控制台上可以看到以下輸出:
清空控制台,點擊“ChangeParamter”按鈕,可以觀測到頁面上的Title位置的值發生了變化,控制台的輸出結果如下:
清空控制台,點擊“Click me”按鈕,可以看到Current count后面的值增加了1,控制台的輸出結果如下:
清空控制台,點擊“NotifyStateHasChanged”按鈕,可以看到頁面並沒有發生變化,不過,控制台的輸出結果如下:
本文參考: