最近,在 Ant Design Blazor 元件庫中實現多標籤頁元件的呼聲日益高漲。於是,我利用週末時間,結合 Blazor 內建路由元件實現了基於 Tabs
元件的 ReuseTabs
元件。
前言
Blazor 是 .NET 最新的前端框架,可以基於 WebAssembly 或 SignalR (WebSocket)構建前端應用程式,基於 WebAssembly 託管模型的 Blazor 甚至可以離線執行。再加上可以共用 .NET 類庫,能使程式碼量比以往的基於 JS 的前後端分離模型少 1/3。而且現在 .NET 開發者也可以使用自己熟悉的技術和經驗來開發前端應用了,不同技術棧的開發人員之間的溝通成本也大大減少,從而再一次解放了生產力。
所以,Blazor 是 .NET 開發者的又一生產力技術!
通過使用 Blazor 社群生態開源的 UI 元件庫,常用的元件都被封裝了起來,使用者再也不需要寫 JS 和 CSS 了,使得 .NET 開發人員在社群裡連連稱讚。目前,已經有大量的基於 Blazor 構建的企業級應用程式被部署上線,逐漸被企業認可。
正文
什麼是路由複用多標籤頁
本文標題中的路由複用,是 Angular 的 RouteReuseStrategy
中的概念,在中文社群也常被稱作“多標籤頁”,主要的功能是當切換頁面時,保持頁面的狀態,並且可以通過任意切換頁面,當前展示的頁面狀態能夠恢復。通常是被用在比較複雜的後臺管理系統,使用者可以在篩選了表格後,進入記錄的詳情頁,再回到列表頁後,仍然能保持原來的搜尋條件、翻頁數等等;也或者是填寫表單時,需要去別的頁面檢視正確的資訊,在回到表單時,表達上已填過的內容不會丟失。
而由於天然的能複用 C# 程式碼的優勢, Blazor 通常被用於構建後臺管理系統,所以使用標籤頁就成為了普遍的需求。然鵝,Blazor 官方團隊並沒有給我們直接提供這樣的元件,所以就需要社群的小夥伴來實現了。
但是縱觀社群中的幾個開源元件庫,都只是實現了通用的 Tabs 標籤頁元件,只能當作切換面板來使用。要用來實現“多標籤頁”的功能,要麼不支援,要麼還得要直接或間接地依賴自己選單元件和佈局元件,再要依賴頁面檔案路徑,拼接出頁面元件的型別,最後用反射來建立頁面元件……
雖然說它們確實實現了多標籤頁的功能,但是實現方式不甚優雅。耦合度非常高,只能在元件庫自己的框架佈局中使用,而不能單獨拎出來使用。另外,反射的效能也不好,還要把頁面按照約定放置,對使用者種種制約。
當然,社群中還流傳一個比較認可的方案,就是 BlazorDemoMultiPagesTab
專案。它提供了一個原型,通過結合 Blazor 內建的路由元件實現了路由多標籤頁。但問題是它只是一個 demo,只實現了原理,程式碼比較凌亂,作者也沒有再做整理,也沒有封裝成元件,如果想在自己專案中使用起來,肯定會薅禿自己的頭髮的。
Ant Design Blazor 中的 ReuseTabs 元件
最近,在 Ant Design Blazor 元件庫中實現多標籤頁元件的呼聲日益高漲。於是,我利用週末時間,基於 BlazorDemoMultiPagesTab
中提供的思路,結合 Blazor 內建路由元件實現了基於 Tabs
元件的 ReuseTabs
元件。
ReuseTabs
元件只包含兩個子元件,ReuseTabsRouteView
和 ReuseTabs
,其中 ReuseTabsRouteView
繼承自內建的 RouteView
元件,負責接管頁面元件的生命週期,使頁面元件能夠保持狀態或被銷燬;ReuseTabs
負責標籤的展示和互動。除此之外,沒有再依賴選單、佈局之類的其他元件,因此可以直接用於任何 Blazor 應用程式,也可以很好地與其他元件庫一起使用。
主要的特點
- 只需修改兩處程式碼即可應用
- 支援靜態或動態地設定標籤名
- 與路由同步,支援
<a>
標籤、NavigationManger
等各種方式的跳轉
下面介紹一下基礎的使用方法,以 dotnet new 模板專案為例。
使用方法
首先,按照 Ant Design Blazor 文件中介紹的方式安裝 AntDesign 包和服務註冊。
然後,修改專案中的
App.razor
檔案,把RouteView
替換成ReuseTabsRouteView
。<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
- <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" / >
+ <ReuseTabsRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
...
</Router>
修改專案中的
MainLayout.razor
檔案,@inherits LayoutComponentBase <div class="page">
<div class="sidebar">
<NavMenu />
</div> <div class="main">
- <div class="top-row px-4">
- <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
- </div>
- <div class="content px-4">
- @Body
- </div>
+ <ReuseTabs Class="top-row px-4" TabPaneClass="content px-4" / >
</div>
</div>
兩種方式自定義標籤名
- 如果是純文字,可以在頁面元件使用
ReuseTabsPageTitle
特性。
@page "/counter"
+ @attribute [ReuseTabsPageTitle("Counter")]
- 如果需要使用模板來獲取動態的標籤名,比如新增另一個元件,或者從頁面內容中獲取標題,需要實現
IReuseTabsPage
介面:
@page "/"
+ @implements IReuseTabsPage <h1>Hello, world!</h1> @code{
+ public RenderFragment GetPageTitle() =>
+ @<div>
+ <Icon Type="home"/> Home
+ </div>
+ ;
}
- 如果是純文字,可以在頁面元件使用
注意:當前 ReuseTabs
元件在 0.9.0 版本的每日構建包中,在正式釋出之前,需要參考文件中介紹的方式來安裝。
後續功能
目前該元件只實現了基本的功能,還有一些功能在後續的計劃當中:
- 右鍵選單
- 程式碼方式關閉
- 快取策略
- 路由守衛與許可權控制
後記
Blazor 社群中對多標籤頁的呼聲有一年多了,這幾天終於實現了,國內外的社群都一片歡騰,也是頗有成就感的。
對於實現的細節,感興趣的同學可以到 Ant Design Blazor 的原始碼中檢視,也只是幾個檔案。當然,如果感興趣的同學比較多,我也可以寫一篇詳細的文章來介紹。
其實我是比較希望社群中能有更多的愛好者站出來,分享心得、貢獻開源專案,這樣才能讓社群健康發展起來。
Ant Design Blazor 發展至今已有一年有多,但是說實話相對於其他元件庫專案的作者,我自己的投入的時間和貢獻並沒有很多。其中除了貢獻程式碼,一大部分精力都花在了社群的運營。
為專案作宣傳,把路人變成使用者,再把使用者變成貢獻者,讓更多人各自花少量精力,達到眾人拾柴的效果,才是開源專案得以長期活躍的長久之計。
最後還是非常感激支援我們的使用者和貢獻者!他們的每個 issue、案例和 PR 都是對我們的肯定,也是讓我們堅持的動力!
參考連結
- https://github.com/BlazorPlus/BlazorDemoMultiPagesTab
- https://github.com/ant-design-blazor/demo-reuse-tabs
- https://antblazor.com/docs/nightly-build