[Mvp.Blazor] 动态路由与钩子函数
(Blazor組件的生命周期函數(shù))
一直在學(xué)習(xí)也沒有停下腳步,用著腦子還是挺好的,感覺可以更腳踏實(shí)地一下。
最近偶爾也繼續(xù)看了看Blazor,畢竟我也開源了一個(gè)項(xiàng)目嘛,基本我正式開源的項(xiàng)目都會(huì)負(fù)責(zé)到底,所以該有的功能都要有的
(https://github.com/anjoy8/Blog.MVP.Blazor)
通過幾天的學(xué)習(xí),感覺愈發(fā)的感覺這門技術(shù)很棒,主要是很對(duì)我的脾氣,用c#開發(fā)前端組件,生成交互式客戶端 Web UI 的框架,一直是我連想象都不敢想的事情,不僅僅是它擁有組件繼承、數(shù)據(jù)綁定、js交互、組件通訊等等前端比較亮眼的功能,最讓我開心的就是他同樣也有自己的生命周期,也就是文章的標(biāo)題——鉤子函數(shù)。要知道生命周期在前端框架開發(fā)中,還是有舉足輕重的地位的。
那咱們暫時(shí)先不說這個(gè)鉤子,先說下今天要干的事情,如何實(shí)現(xiàn)動(dòng)態(tài)路由。
1、為什么要實(shí)現(xiàn)動(dòng)態(tài)路由?
咱們先看看我之前是怎么做的,在blazor項(xiàng)目中,我們是這樣設(shè)計(jì)的:
除了新增和刪除外,就是展示頁面,主要是按照一定的分類進(jìn)行展示,所以呢,當(dāng)時(shí)我為了圖省事,每一個(gè)分類一個(gè)頁面,每個(gè)頁面發(fā)送同樣的請(qǐng)求,所以基本的代碼都一樣:
每個(gè)頁面定義各自的路由地址:
@page "/aspnetcore-abp-blazor/2020" @page "/identityserver4/2020" @page "/azure/2020"純手動(dòng)硬編碼操作,雖然創(chuàng)建了一個(gè)自定義組件,但是這種開發(fā)模式肯定是不可取的,不僅從軟件開發(fā)上沒有實(shí)現(xiàn)封裝,而且在后期多個(gè)分類的時(shí)候,還要去創(chuàng)建頁面,無法實(shí)現(xiàn)多態(tài)的,所以基于這個(gè)想法呢,我就覺得做個(gè)動(dòng)態(tài)路由,其實(shí)在MVC開發(fā)中,也就是我們特別常見,也是玩膩的操作——把分類做個(gè)url參數(shù)來實(shí)現(xiàn)。
那具體如何實(shí)現(xiàn)呢,請(qǐng)繼續(xù)往下看。
2、如何實(shí)現(xiàn)動(dòng)態(tài)路由?
簡(jiǎn)單翻看官網(wǎng),我們就看到了很清晰的介紹,然后快速的,大刀闊斧的開發(fā)了:
首先刪掉那幾個(gè)手寫的分類頁面,保留一個(gè)List.razor組件,Blogs文件夾主要就是實(shí)現(xiàn)動(dòng)態(tài)展示,然后Post文件夾,用來進(jìn)行修改和新增,更像是一個(gè)后臺(tái)管理,而且是帶權(quán)限那種(這里埋一個(gè)坑吧,目前還是沒有研究透如何在Blazor.Server中集成Ids4,以后再看看)。
然后定義動(dòng)態(tài)路由:
@page "/{type}/{year}"@code {[Parameter]public string type { get; set; } = "";[Parameter]public string year { get; set; } = "2020";private int num = 0;private MessageModel<List<BlogArticle>> _blogs;protected override async Task OnParametersSetAsync(){this._blogs = await Http.GetFromJsonAsync<MessageModel<List<BlogArticle>>>("http://apk.neters.club/api/Blog/GetBlogsByTypesForMVP?types=" + type);num = 0;} }核心的就是配置@page,然后還有定義兩個(gè)必須是Public的變量參數(shù),注意要增加特性[Parameter],不然就是普通的變量,從而無法url獲取到指定的值。
看似一切很正常,也是和我想的一樣,通過不同的url來訪問,就能獲取指定的內(nèi)容,但是這個(gè)時(shí)候有一個(gè)小問題,如果在當(dāng)前頁面內(nèi),進(jìn)行標(biāo)簽參數(shù)切換的話,就不行了。
但是加載后,跳轉(zhuǎn)到首頁,再點(diǎn)另一個(gè)分類,這樣肯定是可以的。
那這是為什么呢?欸,這就引出了今天的重頭戲——生命周期。
3、Blazor的生命周期
Blazor的生命周期與React組件的生命周期類似,分為三個(gè)階段:初始化、運(yùn)行中和銷毀階段,其相關(guān)方法有10個(gè),包括設(shè)置參數(shù)前、初始化、設(shè)置參數(shù)之后、組件渲染后以及組件的銷毀,但是這些方法有些是重復(fù)的,只不過是同步與異步的區(qū)別。
我因?yàn)橛蠷eact的基礎(chǔ),所以看起來一目了然,當(dāng)然如果你沒學(xué)過React,但是學(xué)過Vue也行呀,畢竟我們Vue八個(gè)生命周期四個(gè)階段都學(xué)過了,三個(gè)階段的Blazor,學(xué)起來還不是分分鐘的事兒。這就是文章開頭的那張流程圖。
具體的加載流程呢,我就不一一調(diào)試了,反正你打個(gè)斷點(diǎn),或者console輸出一下,就能大概明白其中的過程是怎樣的,這里說說那幾個(gè)鉤子函數(shù):
(同步方法先于異步方法執(zhí)行)
| 1 | 設(shè)置參數(shù)前 | SetParametersAsync |
| 2 | 初始化 | OnInitialized/OnInitializedAsync |
| 3 | 設(shè)置參數(shù)后? | OnParametersSet/OnParametersSetAsync |
| 4 | 組件渲染呈現(xiàn)后 | OnAfterRender/OnAfterRenderAsync |
| 5 | 判斷是否渲染組件 | ShouldRender |
| 6 | 組件刪除前 | Dispose |
| 7 | 通知組件渲染 | StateHasChanged |
到了這里我們應(yīng)該明白了,其實(shí)我們使用的是OnInitializedAsync鉤子,是指我們的頁面初始化完成后所執(zhí)行的方法:
我們第一次訪問的時(shí)候,肯定是執(zhí)行一次初始化,但是實(shí)現(xiàn)了動(dòng)態(tài)路由以后,在當(dāng)前頁面針對(duì)不同的標(biāo)簽進(jìn)行切換的時(shí)候,其實(shí)已經(jīng)不會(huì)再走初始化的鉤子了。
那我就選擇了一個(gè)其他的鉤子,比如OnParametersSetAsync,設(shè)置參數(shù)后來實(shí)現(xiàn)數(shù)據(jù)源的獲取,修改代碼:
//protected override async Task OnInitializedAsync()//{// this._blogs = await Http.GetFromJsonAsync<MessageModel<List<BlogArticle>>>("http://apk.neters.club/api/Blog/GetBlogsByTypesForMVP?types=" + type);// _blogs2 = _blogs.response;//}protected override async Task OnParametersSetAsync(){this._blogs = await Http.GetFromJsonAsync<MessageModel<List<BlogArticle>>>("http://apk.neters.club/api/Blog/GetBlogsByTypesForMVP?types=" + type);_blogs2 = _blogs.response;num = 0;}這個(gè)時(shí)候,我們?cè)冱c(diǎn)擊標(biāo)簽切換的時(shí)候,就很隨心所欲了。
經(jīng)過測(cè)試已經(jīng)沒有問題了,你可以體驗(yàn)一下:
https://mvp.neters.club/
4、其他功能美化
文章編號(hào)
除了實(shí)現(xiàn)上邊的動(dòng)態(tài)路由以為,還簡(jiǎn)單的實(shí)現(xiàn)了文章編號(hào)的功能:
其實(shí)也是很簡(jiǎn)單的,而且也簡(jiǎn)單的寫了一個(gè)填充的擴(kuò)展——不足2位添0:
/// <summary>/// /// </summary>/// <param name="thisValue"></param>/// <param name="fillDigits">填充位數(shù)</param>/// <returns></returns>public static string ObjToStringFill2(this int thisValue, int fillDigits = 2){if (thisValue >= 0 && thisValue < 10){return thisValue.ToString().PadLeft(fillDigits, '0');}return thisValue.ObjToString();}搜索功能
之前我們說過Blazor是支持雙向綁定的,那我們就基于這個(gè)功能,實(shí)現(xiàn)搜索功能:
好啦,今天的內(nèi)容就暫時(shí)到這里了,通過很小的功能,相信你應(yīng)該對(duì)Blazor的鉤子函數(shù),動(dòng)態(tài)路由,數(shù)據(jù)綁定有了一定的認(rèn)識(shí)和了解了吧。
下次再見咯。
總結(jié)
以上是生活随笔為你收集整理的[Mvp.Blazor] 动态路由与钩子函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Blazor带我重玩前端(一)
- 下一篇: .NET Core + Kubernet