ASP.NET Core Blazor简介和快速入门二(组件基础之组件生命周期)
大家好,我是码农刚子。上一章介绍了Blazor的简介,开发工具及环境,基本语法和一些示例。接下来我们继续了解Blazor 组件相关的基础知识,希望对你有所帮助。
1、组件生命周期
1.简介
Blazor的生命周期与React组件的生命周期类似,也分为三个阶段:初始化阶段、运行中阶段和销毁阶段,其相关方法有10个,包括设置参数前、初始化、设置参数之后、组件渲染后以及组件的销毁,但是这些方法有些是重复的,只不过是同步与异步的区别。
2.图解
首先将结果图呈现,代码位于第3部分:

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事件处理等)中被调用。
3.代码示例
设置参数时 (SetParametersAsync)
SetParametersAsync 设置由组件的父组件在呈现树或路由参数中提供的参数。
每次调用 ParameterView 时,方法的 参数都包含该组件的SetParametersAsync值集。 通过重写 SetParametersAsync 方法,C#代码可以直接与 ParameterView 参数交互。
@page "/set-params-async/{Param?}"
<PageTitle>Set Parameters Async</PageTitle>
<h1>Set Parameters Async Example</h1>
<p>@message</p>
@code {
private string message = "Not set";
[Parameter]
public string? Param { get; set; }
public override async Task SetParametersAsync(ParameterView parameters)
{
if (parameters.TryGetValue<string>(nameof(Param), out var value))
{
if (value is null)
{
message = "The value of 'Param' is null.";
}
else
{
message = $"The value of 'Param' is {value}.";
}
}
await base.SetParametersAsync(parameters);
}
}
组件初始化 (OnInitialized{Async})
OnInitialized 和 OnInitializedAsync 专门用于在组件实例的整个生命周期内初始化组件。 参数值和参数值更改不应影响在这些方法中执行的初始化。 例如,将静态选项加载到下拉列表中,该下拉列表在组件的生命周期内不会更改,也不依赖于参数值,这是在这些生命周期方法之一中执行的操作。 如果参数值或参数值更改会影响组件状态,请改为使用 OnParametersSet{Async}。
组件在接收 SetParametersAsync 中的初始参数后初始化,此时,将调用这些方法。
如果使用同步父组件初始化,则保证父组件初始化在子组件初始化之前完成。 如果使用异步父组件初始化,则无法确定父组件和子组件初始化的完成顺序,因为它取决于正在运行的初始化代码。
对于同步操作,重写 OnInitialized:
@page "/on-init"
<PageTitle>On Initialized</PageTitle>
<h1>On Initialized Example</h1>
<p>@message</p>
@code {
private string? message;
protected override void OnInitialized() =>
message = $"Initialized at {DateTime.Now}";
}
若要执行异步操作,请替代 OnInitializedAsync 并使用 await 运算符:
protected override async Task OnInitializedAsync()
{
//await ...
await Task.Delay(2000); //2秒之后
message = $"Initialized at {DateTime.Now} after 2 second delay";
}
如果自定义基类与自定义初始化逻辑一起使用,需在基类上调用 OnInitializedAsync:
protected override async Task OnInitializedAsync()
{
await ...
await base.OnInitializedAsync();
}
设置参数之后 (OnParametersSet{Async})
OnParametersSet 或 OnParametersSetAsync 在以下情况下调用:
- 在 OnInitialized 或 OnInitializedAsync 中初始化组件后。
- 当父组件重新呈现并提供以下内容时:
- 至少一个参数已更改时的已知或基元不可变类型。
- 复杂类型的参数。 框架无法知道复杂类型参数的值是否在内部发生了改变,因此,如果存在一个或多个复杂类型的参数,框架始终将参数集视为已更改。
在组件路由中,不能同时对DateTime参数使用datetime路由约束,并将该参数设为可选。 因此,以下 OnParamsSet 组件使用两个 @page 指令来处理具有和没有 URL 中提供的日期段的路由。
@page "/on-params-set"
@page "/on-params-set/{StartDate:datetime}"
<PageTitle>On Parameters Set</PageTitle>
<h1>On Parameters Set Example</h1>
<p>
Pass a datetime in the URI of the browser's address bar.
For example, add <code>/1-1-2024</code> to the address.
</p>
<p>@message</p>
@code {
private string? message;
[Parameter]
public DateTime StartDate { get; set; }
protected override void OnParametersSet()
{
if (StartDate == default)
{
StartDate = DateTime.Now;
message = $"No start date in URL. Default value applied " +
$"(StartDate: {StartDate}).";
}
else
{
message = $"The start date in the URL was used " +
$"(StartDate: {StartDate}).";
}
}
}
应用参数和属性值时,异步操作必须在 OnParametersSetAsync 生命周期事件期间发生:
protected override async Task OnParametersSetAsync()
{
await ...
}
如果自定义基类与自定义初始化逻辑一起使用,需在基类上调用 OnParametersSetAsync:
protected override async Task OnParametersSetAsync()
{
await ...
await base.OnParametersSetAsync();
}
组件呈现之后 (OnAfterRender{Async})
OnAfterRender 和 OnAfterRenderAsync 在组件以交互方式呈现并且 UI 完成更新之后被调用(例如,元素添加到浏览器 DOM 之后)。 此时会填充元素和组件引用。 在此阶段中,可使用呈现的内容执行其他初始化步骤,例如与呈现的 DOM 元素交互的 JS 互操作调用。
这些方法不会在预呈现或静态服务器端渲染(静态 SSR)期间在服务器上调用,因为这些进程未附加到实时浏览器 DOM,并且已在 DOM 更新之前完成。
对于 OnAfterRenderAsync,组件在任何返回 Task 的操作完成后不会自动重渲染,以避免无限渲染循环。
firstRender 和 OnAfterRender 的 OnAfterRenderAsync 参数:
- 在第一次呈现组件实例时设置为
true。 - 可用于确保初始化操作仅执行一次。
@page "/after-render"
@inject ILogger<AfterRender> Logger
<PageTitle>After Render</PageTitle>
<h1>After Render Example</h1>
<p>
<button @onclick="HandleClick">Log information (and trigger a render)</button>
</p>
<p>Study logged messages in the console.</p>
@code {
protected override void OnAfterRender(bool firstRender) =>
Logger.LogInformation("firstRender = {FirstRender}", firstRender);
private void HandleClick() => Logger.LogInformation("HandleClick called");
}
加载页面并选择按钮时,AfterRender.razor 示例向控制台输出以下内容:

在渲染后立即进行的异步工作必须在 OnAfterRenderAsync 生命周期事件期间发生:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
...
}
如果自定义基类与自定义初始化逻辑一起使用,需在基类上调用 OnAfterRenderAsync:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
...
await base.OnAfterRenderAsync(firstRender);
}
基类生命周期方法
重写 Blazor 的生命周期方法时,无需为 ComponentBase 调用基类生命周期方法。 但在以下情况下,组件应调用重写的基类生命周期方法:
- 重写 ComponentBase.SetParametersAsync 时,通常会调用
await base.SetParametersAsync(parameters);, 因为基类方法会调用其他生命周期方法并以复杂的方式触发渲染。 有关详细信息,请参阅设置参数时 (SetParametersAsync) 部分。 - 如果基类方法包含必须执行的逻辑。 库使用者通常在继承基类时调用基类生命周期方法,因为库基类通常具有要执行的自定义生命周期逻辑。 如果应用使用某个库中的基类,请参阅该库的文档以获取指导。
以下示例中调用了 base.OnInitialized(); 以确保会执行基类的 OnInitialized 方法。 如果没有调用,BlazorRocksBase2.OnInitialized 不会执行。
@page "/blazor-rocks-2"
@inherits BlazorRocksBase2
@inject ILogger<BlazorRocks2> Logger
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 2</h1>
<p>
@BlazorRocksText
</p>
@code {
protected override void OnInitialized()
{
Logger.LogInformation("Initialization code of BlazorRocks2 executed!");
base.OnInitialized();
}
}
using Microsoft.AspNetCore.Components;
namespace BlazorAppWasm
{
public class BlazorRocksBase2: ComponentBase
{
[Inject]
private ILogger<BlazorRocksBase2> Logger { get; set; } = default!;
public string BlazorRocksText { get; set; } = "Blazor rocks the browser!";
protected override void OnInitialized() =>
Logger.LogInformation("Initialization code of BlazorRocksBase2 executed!");
}
}
以上就是关于《ASP.NET Core Blazor简介和快速入门二(组件基础之组件生命周期)》的全部内容,希望你有所收获。关注我,持续分享。
- 点赞
- 收藏
- 关注作者
评论(0)