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 = ; 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源码

Blazor入门笔记(4)-组件的生命周期的更多相关文章

  1. Blazor入门笔记(6)-组件间通信

    1.环境 VS2019 16.5.1.NET Core SDK 3.1.200Blazor WebAssembly Templates 3.2.0-preview2.20160.5 2.简介 在使用B ...

  2. ReactJS入门(二)—— 组件的生命周期

    如果你熟悉avalon,使用过 data-include-rendered 和 data-include-loaded 等回调方法,那么你会很好地理解React组件的各个生命周期. 说白了其实就是Re ...

  3. reactjs入门到实战(七)---- React的组件的生命周期

    React的组件的生命周期有三个状态分别是:挂载(生产组件示例化.准备挂载到页面.挂载到页面).更新(更新值.更新DOM).和卸载(卸载后). >>>其他     getInitia ...

  4. ReactJS入门3:组件的生命周期

    本文主要介绍组件的生命周期. 组建的生命周期主要分为3个:Mounting.Updating.Unmounting. 1. Mounting:组件被加载到DOM     在本阶段,主要有三个方法: 1 ...

  5. react 入坑笔记(六) - 组件的生命周期

    React 组件生命周期 详细参考: react 组件生命周期 组件的生命周期可分为三个状态: 1.Mounting:已经挂载/插入到真实 DOM 树上: 2.Updating:正在被重新渲染: 3. ...

  6. 【React】学习笔记(二)——组件的生命周期、React脚手架使用

    原教程视频:ttps://www.bilibili.com/video/BV1wy4y1D7JT?p=2&spm_id_from=pageDriver 目录 一.组件的生命周期 1.1.生命周 ...

  7. Jetpack 架构组件 Lifecycle 生命周期 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  8. react(一):组件的生命周期

    最近兄弟团队让我去帮忙优化两个页面,前端用的react全家桶,后端用的python,上一次写react代码都过去一年了,顺着以前的的学习思路,再捋顺一下react的要点 组件的生命周期就是Reac的工 ...

  9. 【老孟Flutter】Stateful 组件的生命周期​

    老孟导读:关于生命周期的文章共有2篇,第一篇是介绍 Flutter 中Stateful 组件的生命周期. 博客地址:http://laomengit.com/blog/20201227/Statefu ...

随机推荐

  1. JZOJ 3518. 【NOIP2013模拟11.6A组】进化序列(evolve)

    3518. [NOIP2013模拟11.6A组]进化序列(evolve) (File IO): input:evolve.in output:evolve.out Time Limits: 1000 ...

  2. FreeModBus源码解析(1)---开篇

    一.设计思想 任何通信协议的实现都是基于状态机的设计思想,就是来了一串数据判断是是干啥的在调用相应的处理函数只不过高手一般采用回调处理. 如果你熟悉了回调.源码里的状态机的实现又可以理解,那么恭喜你已 ...

  3. SQL数据库中的增删改查总结1

    一.增:有2种方法 1.使用insert插入单行数据: 语法:insert [into]<表名> [列名] values <列值> 例:insert into Strdents ...

  4. Markdown语法说明及常用软件推荐(附链接)

    Markdown语法同样支持HTML标签 以下所有字符均为英文字符 标题 标题级别由#决定,一个为一级 样例 # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ...

  5. proteus pro 8.9 安装及汉化教程

    最近由于网上上课老师要求我们自己安装proteus这款仿真软件,所以笔者也安装了最新款版的proteus pro 8.9,分享给大家安装心得,也包含汉化过程,希望大家能用软件好好学习. 备注:感谢博主 ...

  6. vue安卓4.4.2页面打不开的坑

    项目上线两三天,有保障说安卓下面页面打不开,所以查了下具体原因,系统版本过低,安卓4.4.2,然后发现本地没有babel-polyfill的包,具体解决方案如下: 1,npm 安装 npm insta ...

  7. 《JavaScript 模式》读书笔记(1)— 简介

    哇,看了自己最近的一篇文章,其实那时候刚接触Jest,啥也不会(虽然现在其实也一样不会,嘿嘿),就像记录下工作中遇到的一些问题,其实,后来的一些发现吧,那两篇文章写的其实是有一些问题的.希望不会给大家 ...

  8. cocoapods安装以及ZXingObjC的安装

    因为项目要用到第三方包ZXingObjC,需要安装cocoapods.下面是我曲折的安装过程. 1.直接在终端内输入: sudo gem install cocoapods 我直接安装成功. 由于国内 ...

  9. mysql实现读写分离

    MySQL读写分离概述 1.读写分离介绍 对于目前单机运行MySQL服务.会导致MySQL连接数过多.最终导致mysql的宕机.因此可以使用多台MySQL服务器一起承担压力.考虑到项目中读写比例的不一 ...

  10. Leetcode 1160: 拼写单词

    给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars. 假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌 ...