Blazor和Vue对比学习(进阶.生命周期-1):基本理解和使用

一、基本理解:首次接触“生命周期”这个名词,是比较晦涩的,Vue中有生命周期钩子,而Blazor则是虚方法重写,容易蒙。所以,我尝试从初学者的角度来阐述一下。

  1. 我们在基础部分已经知道,组件有两部分组成,一是逻辑层,有数据和方法(方法本质上也是数据);二是视图层,虽然有自定义组件,但拆到底,还是HTML原生标签。
  2. 组件的初次呈现,可以先简单的理解为两个过程,第一步,完成逻辑层的实例化,类似于一个类的实例化,为视图层准备数据;第二步,完成视图层DOM的渲染,会使用到逻辑层的数据。这个过程,可以认为就是生命周期,当然我们需要继续细化。
  3. 在这个生命周期中,我们肯定想做两件事情,一是当到达特定阶段时,让我知道,这样我可以执行某些任务;二是我还能根据一些情况的判断,来决定生命周期是否继续执行。
  4. 为了实现上面的两件事情,Vue为我们准备了不同阶段的生命周期钩子,Blazor则是虚方法。两者的原理是一样的,本质上,是一种命名约定和方法重写。如在完成视图层的DOM渲染后,Vue执行一个名字叫onMounted()的方法,Blazor则执行一个名字叫OnAfterRender()的方法。Vue中,我们使用回调,Blazor中我们通过重写override,就能实现自己想执行的逻辑。
  5. Blazor的生命周期,使用虚方法和方法重写,有C#基础的会比较容易理解,如果看Blazor生命周期的源码,里面有很多类似这样的代码:if(某某状态出现){则调用某个方法},条件就是用来判断生命周期到哪个阶段了,方法体中调用的方法就是Blazor的生命周期虚方法。而Vue的钩子,虽然易用,但要想理解通透了,则更加晦涩一些。

 

二、基本使用

两者的使用语法都较简单,直接在逻辑层,按约定写方法就可以。但要使用得当且灵活运用,还是需要了解每一个生命周期过程的细节,尤其是Blazor,会相对复杂一些。Blazor提供了更加丰富的控制方法,但也提高了使用的复杂度。对生命周期细节更深入的学习,我们放到第二节,这节先简单了解一下

1、 Vue的生命周期钩子,作为API导入,方法体中写回调逻辑。

//Vue===============================================================================================

onBeforeMount(()=>{console.log("组件渲染/挂载前")})
onMounted(()=>{console.log('组件渲染/挂载后')})

onBeforeUpdate(()=>{console.log('数据更新前')})
onUpdated(()=>{console.log('数据更新后')})

onBeforeUnmount(()=>{console.log('组件销毁前')})
onUnmounted(()=>{console.log('组件销毁后')})

 

2、Blazor直接重写生命周期函数(方法签名一致),方法体中写自己的逻辑,部分虚函数提供了入参

//Blazor=============================================================================================

public override async Task SetParametersAsync(ParameterView parameters)
{
    Console.WriteLine("[Parameter]参数设置前"); 
    await base.SetParametersAsync(parameters);  
    //收集外部传参到ParameterView,未给[Parameter]参数属性赋值
    //最后执行【base.SetParametersAsync】,给[Parameter]参数属性赋值
}

protected override void OnInitialized()
{
    Console.WriteLine("组建初始化"); 
    //创建组件实例,完成组件逻辑层的初始化,包括字段、属性等的初始化
    //有一个配对的异步函数OnInitializedAsync,如果同步和异步都设置了,则先执行同步,再执行异步
}

protected override void OnParametersSet()
{
    Console.WriteLine("参数设置后"); 
    //[Parameter]参数属性更新时执行,当然,首次赋值时也会执行
    //OnInitialized只在组件初始化时执行一次,参数更新时,并不执行//有一个配对的异步函数OnParametersSetAsync,如果同步和异步都设置了,则先执行同步,再执行异步
}

protected override void OnAfterRender(bool firstRender)
{
    Console.WriteLine("组件渲染后"); 
    //DOM完成渲染后,此时可以获得最新的ref
    //是否渲染DOM,根据虚拟DOM的差量算法
    //可能引起渲染:父组件重新渲染、[Parameter]参数属性变化、本组件字段/属性变化、本组件事件执行等
    //有一个配对的异步函数OnAfterRenderAsync,如果同步和异步都设置了,则先执行同步,再执行异步
//回调中可以获得一个布尔类型参数firstRender,如果是首次渲染,则为true,如果不是,则为false
} //Dispose不属于生命函数,所以用法比较特别,先实现IDisposable或IAsyncDisposable接口,然后调用接口的Dispose或DisposeAsync方法 //如果组件使用了非托管资源,比如计时器、导航事件等,必须在Dispose或DisposeAsync方法中释放资源,否则框架会认为组件还在使用,不会回收组件,会造成内存泄露
//IAsyncDisposable相应的调用方法为【public async ValueTask DisposeAsync(){}】
@implements IDisposable @code { public void Dispose() { Console.WriteLine("组件销毁"); } }

 

posted @ 2022-05-21 20:47  functionMC  阅读(963)  评论(0编辑  收藏  举报