Blazor入门笔记(4)-组件的生命周期

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”按钮,可以看到页面并没有发生变化,不过,控制台的输出结果如下:

代码:GtiHub LearningBlazor

本文参考:

ASP.NET Core Blazor 生命周期

ComponentBase源码

posted @ 2020-04-05 18:01  半野  阅读(3249)  评论(2编辑  收藏  举报