Blazor和Vue對比學習(進階2.1.1):生命周期,基本理解和使用
- 2022 年 5 月 21 日
- 筆記
- Blazor, MAUI/WPF/Blazor/Vue/, VUE
一、基本理解
首次接觸「生命周期」這個名詞,是比較晦澀的,Vue中又有生命周期鉤子,而Blazor則是虛方法重寫,容易蒙。所以,我嘗試從初學者的角度來闡述一下。
1、我們在基礎部分已經知道,組件有兩部分組成,一是邏輯層,有數據和方法(方法本質上也是數據);二是視圖層,雖然有自定義組件,但拆到底,還是HTML原生標籤。
2、組件的初次呈現,可以先簡單的理解為兩個過程,第一步,完成邏輯層的實例化,類似於一個類的實例化,為視圖層準備數據;第二步,完成視圖層DOM的渲染,會使用到邏輯層的數據。這就是生命周期,當然中間過程我們需要繼續細化。
3、在這個生命周期中,我們肯定想做兩件事情,一是當到達特定階段時,讓我知道,這樣我可以執行某些任務;二是我還能根據一些情況的判斷,來決定生命周期是否繼續執行。
4、為了實現上面的兩件事情,Vue為我們準備了不同階段的生命周期鉤子,Blazor則是虛方法。兩者的原理是一樣的,本質上,是一種命名約定和方法重寫。如在完成視圖層的DOM渲染後,Vue執行一個名字叫onMounted()的方法,Blazor則執行一個名字叫OnAfterRender()的方法。Vue中,我們使用回調,Blazor中我們通過重寫override,就能實現自己想執行的邏輯。
5、Blazor生命周期的使用,更加接近於本質,虛方法和方法重寫,有C#基礎的,都好理解,而Vue的鉤子,雖然易用,但要想整通透了,則更加晦澀一些。如果看Blazor生命周期的源碼,裡面有很多類似這樣的程式碼:if(某某狀態出現){則調用某個方法},條件就是用來判斷生命周期到哪個階段了,方法體中調用的方法就是Blazor的生命周期虛方法,是不是很容易理解?!
二、基本使用
兩者的語法使用都非常簡單,直接在邏輯層,按約定寫方法就可以。但要使用得當且靈活運用,還是需要了解每一個生命周期過程的細節,尤其是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("參數設置前"); await base.SetParametersAsync(parameters); //完成內部欄位/屬性的初始化,收集外部傳參數到ParameterView,未給參數屬性賦值 //最後執行【base.SetParametersAsync】,給參數屬性賦值 } protected override void OnInitialized() { Console.WriteLine("組建初始化"); //創建組件實例,完成組件的初始化,此時參數屬性已被賦值 //有一個配對的非同步函數OnInitializedAsync } protected override void OnParametersSet() { Console.WriteLine("參數設置後"); //這個生命函數更像是OnInitialized的備胎 //OnInitialized只在組件初始化時執行一次,參數更新時,並不執行 //所以需要一個生命函數來完成OnInitialized做的事情 //有一個配對的非同步函數OnParametersSetAsync } protected override void OnAfterRender(bool firstRender) { Console.WriteLine("組件渲染後"); //DOM完成渲染後,此時可以獲得最新的ref //是否渲染DOM,根據虛擬DOM的差量演算法 //可能引起渲染:父組件重新渲染、父組件傳入的參數屬性變化、本組件欄位/屬性變化、本組件事件執行等 //有一個配對的非同步函數OnAfterRenderAsync } //Dispose不屬於生命函數,所以用法比較特別,先實現IDisposable介面,然後調用介面的Dispose方法 //這個設計比較奇怪的,也沒有查到這麼設計的原因,推斷是防止重複執行,因為Dispose是框架層級的一個方法 @implements IDisposable @code { void IDisposable.Dispose() { Console.WriteLine("組件銷毀"); } }