Blazor和Vue对比学习(进阶.生命周期-2):深入理解生命周期
一、Vue的组件生命周期,理解和使用都比较简单,只说知识点
1、Vue的组件生命周期,总共四个过程:
- 组件初始化(beforeCreate/created),逻辑层数据处理
- 组件挂载(beforeMount/Mounted),首次渲染到视图,形成虚拟DOM
- 组件数据更新(beforeUpdate/updated),逻辑层数据更新时,DOM差量更新
- 组件卸载(beforeUnMount/unMounted),组件实例销毁
- 注:如果使用组合式API,setup替代组件初始化create,实际只剩后面三个过程,挂载>更新>卸载。
2、Vue3组合式API中,生命周期钩子的前缀加on,如onBeforeMount/onMounted。比较常用的钩子就3个,onMounted、onUpdated和onUnMounted。
//挂载后,可以获得组件引用ref <script setup> import { ref, onMounted } from 'vue' const el = ref() onMounted(() => { el.value // 结果为<div> }) </script> <template> <div ref="el"></div> </template>
3、父子组件生命周期的执行顺序,和组件嵌套非常相似(<Parent><Child></Child></Parent>),具体执行顺序如下所示:
- 组件挂载时:父beforeMount>子beforeMount>子mounted>父mounted
- 父组件修改props时:父beforeUndate>子beforeUpdate>子updated>父updated
4、Vue3组合式API的生命周期中,组件挂载时执行一次mount,组件卸载时执行一次unMount,剩下的过程都是数据更新时执行update,比较简单。
5、数据请求时,Vue2中,我们一般写在create或mount钩中子。Vue3中,可以直接写在setup或mount中。如果需要进行响应式的请求,如某个变量更改时,重新请求数据,可以使用watchEffect,详见官网案例。
二、Blazor的生命周期:Blazor和Vue的生命周期,目的都是为了介入组件从创建到销毁的过程,但实现原理和细节差异还是很大。Blazor的生命周期函数更加丰富,但也增加了复杂性,坑多。所以,这个章节,我们重点来剖析Blazor的生命周期。
1、看图讲解(图片来自Blazor University):
1、我们可以将Blazor的生命周期划分为两个大的过程:
(1)初始化:包括三个生命周期函数,①SetParametersAsync;②OnInitialized/OnInitializedAsync;③OnParametersSet/OnParametersSetAsync。这三个生命周期函数,并不一定每次都会执行。
//SetParametersAsync //父组件传入的参数,包含在ParameterView类型的参数parameters中 //ParameterView是一个结构类型,除了传入参数外,还有其它属性和方法 //通过ParameterView,可以对传入的参数进行干预,如判断、设置默认值等 //此函数执行后,子组件 的[Parameter]属性才会更新 public override Task SetParametersAsync(ParameterView parameters) { return base.SetParametersAsync(parameters); } //OnInitialized-OnInitializedAsync //组件逻辑层实例化,且只在创建时执行一次 //首次执行后,如果父级稍后更改组件的参数[parameter],则跳过此方法,直接到OnParametersSet //有一个成对的异步函数,注意异步函数会导致多次Render //一般获取远程数据时,在这个过程中执行 //如果远程数据,在每次[Parameter]改变都要重新获取,则在OnParametersSet中执行 protected override void OnInitialized() { base.OnInitialized(); } //OnParametersSet-OnParametersSetAsync //每次传入参数时,都会执行,此时传入参数已经更新[Parameter]属性 //很像OnInitialized的备胎,执行时间都一样,但OnInitialized只执行一次,它每次都执行 //如果远程数据,在每次[Parameter]改变都要重新获取,则适合在此过程执行。有点类似Vue中watchEffect在获取远程数据中的应用 //也有一个成对的异步函数,同样要注意异步函数的多次Render protected override void OnParametersSet() { base.OnParametersSet(); }
(2)渲染:虽然这个过程,只有一个生命周期函数OnAfterRender/OnAfterRenderAsync,但只要开启组件生命周期,这个函数一定会执行(ShouldRender为true的情况下)。同时,在渲染过程在,提供了StateHasChanged和ShouldRender两个函数,可以对组件的渲染进行控制
//StateHasChanged //在任意位置,只要执行了StateHasChanged(),组件就会Render一次 <button @onclick="@(()=>{StateHasChanged();})">子组件调用StateHasChanged</button> //ShouldRender //ShouldRender是和生命周期一样的虚方法 //重写返回false时,无论判断需不需要Render,组件都不会Render //如果返回True时,无论判断需不需要Render,组件都会Render //如果不重写,则系统自动判断需不需要Render protected override bool ShouldRender() { return false; }
(3)OnInitialized、OnParametersSet和OnAfterRender,均有成对的一个异步函数。Blazor异步生命周期函数有一个特点需要特别注意,调用异步函数时,主线程会一路执行下来,直接Render,异步线程完成后,会再次走Render过程,所以会执行多次Render。但是,OnAfterRender是最后一个过程,其异步不会引起多次Render。
2、父子组件中,不同情况的生命周期过程。注:以上案例,我们简化为初始化和渲染两个大的过程,内部变化和控制以及异步等情况,如以上第1点说明,不再重复。
- 首次加载:=>父组件初始化>子组件初始化>父组件渲染>子组件渲染
- 父组件,改变私有状态(无论是否绑定视图):=>子组件初始化>父组件渲染>子组件渲染
- 父组件,改变传递给子组件的参数(父传子):=>子组件初始化>父组件渲染>子组件渲染
- 父组件,调用StateHasChanged:=>子组件初始化>父组件渲染>子组件渲染
- 父组件,执行任意事件:=>子组件初始化>父组件渲染>子组件渲染
- 子组件,改变私有状态(无论是否绑定视图):=>子组件渲染
- 子组件,调用StateHasChanged:=>子组件渲染
- 子组件,执行任意事件:=>子组件渲染
- 子组件,触发子传父事件:=>子组件初始化>父组件渲染>子组件渲染
3、Blazor默认模板中的天气案例的说明:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战