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. 16 搭建Spring Data JPA的开发环境

    使用Spring Data JPA,需要整合Spring与Spring Data JPA,并且需要提供JPA的服务提供者hibernate,所以需要导入spring相关坐标,hibernate坐标,数 ...

  2. 超详细,多图文使用galera cluster搭建mysql集群并介绍wsrep相关参数

    超详细,多图文使用galera cluster搭建mysql集群并介绍wsrep相关参数 介绍galera cluster原理的文章已经有一大堆了,百度几篇看一看就能有相关了解,这里就不赘述了.本文主 ...

  3. ARM WIFI AP 模式 使用 iptables nat 转发 通过 LAN 网线上网

    编译内核,支持 iptables 和 forward 和 nat. 编译内核,使用新内核启动arm 开发板. 编译内核支持 iptables-> Networking support (NET ...

  4. flask 部署外部访问

    在 app.run(host='0.0.0.0',port=5000) 可以让外部客户端进行访问,访问地址是flask服务器的ip地址和你设置的端口(端口注意不要占用其他端口,如果是阿里云有可能要设置 ...

  5. DevOps - 持续集成

    最近在担任公司部门的DevOps Champion的角色,一直觉得这个只是一个协调者的角色(而不是一个SME的角色),我的工作大概就是将每个项目的devops工具收集一下,然后用图表的形式去体现大家用 ...

  6. AspNetCore源码解析_1_CORS中间件

    概述 什么是跨域 在前后端分离开发方式中,跨域是我们经常会遇到的问题.所谓的跨域,就是处于安全考虑,A域名向B域名发出Ajax请求,浏览器会拒绝,抛出类似下图的错误. JSONP JSONP不是标准跨 ...

  7. R的plotmath

    plotmath plotmath {grDevices}:Mathematical Annotation in R # Copyright (C) 2002-2016 The R Core Team ...

  8. Simulink仿真入门到精通(十六) Simulink基于模型设计的工业应用概述

    16.1 Simulink用途概述 在基于模型设计广泛应用于汽车电子嵌入式开发的今天,MBD(Model Besed Design)技术也逐步推广到各种嵌入式控制方面.与传统的嵌入式开发相比,BMD以 ...

  9. flask连接数据库的URI书写格式

    1. MySQL mysql://username:password@hostname/database 2. PostgreSQL postgresql://username:password@ho ...

  10. 一般人不知道的Flask框架SQLAlchemy的那些事

    目录 SQLAlchemy 1.介绍 2.简单使用(能创建表,删除表,不能修改表) 3.一对多关系 4.多对多关系 5.操作数据表 6.基于scoped_session实现线程安全 7.基本增删查改 ...