ASP.NET Core Blazor简介和快速入门二(组件基础之组件生命周期)

举报
码农刚子 发表于 2025/11/15 23:36:25 2025/11/15
【摘要】 大家好,我是码农刚子。上一章介绍了Blazor的简介,开发工具及环境,基本语法和一些示例。接下来我们继续了解Blazor 组件相关的基础知识,希望对你有所帮助。1、组件生命周期1.简介Blazor的生命周期与React组件的生命周期类似,也分为三个阶段:初始化阶段、运行中阶段和销毁阶段,其相关方法有10个,包括设置参数前、初始化、设置参数之后、组件渲染后以及组件的销毁,但是这些方法有些是重复...

大家好,我是码农刚子。上一章介绍了Blazor的简介,开发工具及环境,基本语法和一些示例。接下来我们继续了解Blazor 组件相关的基础知识,希望对你有所帮助。

1、组件生命周期

1.简介

Blazor的生命周期与React组件的生命周期类似,也分为三个阶段:初始化阶段、运行中阶段和销毁阶段,其相关方法有10个,包括设置参数前、初始化、设置参数之后、组件渲染后以及组件的销毁,但是这些方法有些是重复的,只不过是同步与异步的区别。

2.图解

首先将结果图呈现,代码位于第3部分:

image

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})

OnAfterRenderOnAfterRenderAsync 在组件以交互方式呈现并且 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 示例向控制台输出以下内容:

image

在渲染后立即进行的异步工作必须在 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简介和快速入门二(组件基础之组件生命周期)》的全部内容,希望你有所收获。关注我,持续分享。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。