翻譯自 Waqas Anwar 2021年5月21日的文章 《A Developer’s Guide To Blazor Component Libraries》 [1]
Blazor 的核心是組件,我們創建不同類型的組件並在整個項目中重用它們。沒有人想重復造輪子,因此創建一個可重用的 Blazor 組件庫始終是一個好主意,這些組件不僅可以在多個項目之間共享,還可以作為 NuGet 包與其他人共享。Blazor 允許我們基於一個名為 Razor 類庫(Razor Class Library)的新模板創建這樣的組件庫,在本文中,我將向您演示如何創建這樣一個庫,不僅僅共享組件,還共享靜態內容(比如圖片、樣式表等等)。
創建一個 Razor 組件庫
在 Visual Studio 2019 中創建一個新的名為 BlazorClassLibraryDemo 的 Blazor Server 應用程序,確保您可以正常構建和運行該項目。如果您不確定如何創建 Blazor Server 應用程序,那么我建議您閱讀我的文章《Blazor Server 和 WebAssembly 應用程序入門指南》
要在 Blazor 項目中添加一個新組件庫,請右鍵點擊解決方案並選擇 添加 > 新建項目... 選項。從項目模板列表中選擇 Razor 類庫(Razor Class Library) 項目模板。
為項目提供任意合適的名稱,我這里將其命名為 MyComponentsLibrary。
然后,會詢問您選擇一些其他設置項,直接點擊 創建 按鈕就好。
默認情況下,模板會創建一個名為 Component1.razor 的示例組件和一些附加文件。在開始創建我們的第一個共享組件之前,我們需要刪除 Component1.razor、ExampleJsInterop.cs 以及 wwwroot 文件夾中的所有內容,以便我們有一個純凈的開始。
在 Razor 類庫中創建一個組件
讓我們在 Razor 類庫項目 MyComponentsLibrary 中創建我們的第一個可重用的共享組件。右鍵點擊類庫項目並選擇 添加 > 新建項… 選項。 選擇 Razor 組件 模板並指定組件名稱 TableWidget.razor。
如果您希望將 C# 代碼與組件視圖分開,您還可以添加代碼隱藏文件 TableWidget.razor.cs。該 TableWidget 組件是一個簡單的模板化組件,可用於從任何對象列表生成 HTML 表格。如果您想了解有關 Blazor 模板化組件的更多知識,那么您可以閱讀我的文章《Blazor 模板化組件開發指南》。
在 TableWidget.razor 組件視圖文件中添加以下標記。
TableWidget.razor
@typeparam TItem
<table class="table table-striped table-bordered">
<thead class="thead-green">
<tr>
@HeaderTemplate
</tr>
</thead>
<tbody>
@foreach (var item in Items)
{
<tr>
@RowTemplate(item)
</tr>
}
</tbody>
<tfoot>
<tr>
@FooterTemplate
</tr>
</tfoot>
</table>
下面是 TableWidget 組件的代碼隱藏文件。該組件具有 RenderFragment 類型的 Header、Row 和 Footer 模板,用於在視圖中生成 HTML 表格的表頭、數據行和頁腳。
TableWidget.razor.cs
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
namespace MyComponentsLibrary
{
public partial class TableWidget<TItem>
{
[Parameter]
public RenderFragment HeaderTemplate { get; set; }
[Parameter]
public RenderFragment<TItem> RowTemplate { get; set; }
[Parameter]
public RenderFragment FooterTemplate { get; set; }
[Parameter]
public IReadOnlyList<TItem> Items { get; set; }
}
}
我們在 Razor 類庫中創建的每個可重用組件還可以有對應的樣式表來定義組件的外觀。例如,如果我們希望我們的 TableWidget 組件生成帶有深綠色表頭的表格,我們可以在 TableWidget.razor.css 文件中定義組件的樣式。
TableWidget.razor.css
.thead-green {
background-color: darkgreen;
color: white;
}
使用 Razor 類庫中的 Razor 組件
現在我們已經在類庫項目中定義了我們的 TableWidget 組件,是時候在我們的 Blazor 項目中使用這個組件了。右鍵單擊解決方案資源管理器中的 依賴項(Dependencies) 節點,然后從上下文菜單中選擇 添加項目引用...(Add Project Reference...) 選項。選中 MyComponentsLibrary 項目並點擊確定。
如果您想在多個頁面上使用 TableWidget 組件,那么推薦您在 _Imports.razor 文件中添加該類庫的引用。
@using MyComponentsLibrary
Blazor 項目模板默認生成一個 FetchData.razor 頁面,顯示來自后端服務的天氣預報對象。我們可以在此頁面上測試我們的 TableWidget 組件。打開 FetchData.razor 文件,並使用 TableWidget 組件替換其中的 HTML 表格,如下面的代碼片段所示。
FetchData.razor
@page "/fetchdata"
@using BlazorClassLibraryDemo.Data
@inject WeatherForecastService ForecastService
<h1>Weather forecast</h1>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<TableWidget Items="forecasts" Context="forecast">
<HeaderTemplate>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</HeaderTemplate>
<RowTemplate>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</RowTemplate>
</TableWidget>
}
@code {
private WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
}
}
運行該項目,您會看到使用我們的 TableWidget 組件生成的天氣預報表格。現在,您可以在多個頁面或項目中重用該 TableWidget 組件,並且將會看到始終為您生成相同的表格。
使用 Razor 類庫中的圖片
Razor 類庫可以公開靜態資源(比如圖片),並且這些資源可以由使用該庫的 Blazor 應用程序使用。讓我們在 MyComponentsLibrary 項目的 wwwroot/images 文件夾中添加一個圖片 blazor_logo.jpg。為了在 Blazor 組件中使用此圖片,請在 MyComponentsLibrary 項目中添加一個名為 BlazorLogo.razor 的組件。
使用簡單的 img 標簽將 blazor_logo.jpg 圖片添加到 BlazorLogo.razor 組件中。
BlazorLogo.razor
<img src="images/blazor_logo.jpg" alt="Blazor Logo"/>
要在 Blazor 應用程序中使用此 BlazorLogo.razor 組件,請從我們上面創建的 Blazor 示例應用中打開 Index.razor 頁面,然后直接使用 BlazorLogo 組件,如下面的代碼片段所示。
Index.razor
<h1>Hello, Blazor!</h1>
<BlazorLogo></BlazorLogo>
運行該項目,您會注意到圖片並未如預期那樣顯示出來。這是因為無法從類庫項目外訪問圖片的相對路徑 images/blazor_logo.jpg。
要解決上述問題,您需要使用下面給出的特殊路徑語法:
_content/{Razor Class Library Name}/{Path to file}
在上面的語法中,{Razor Class Library Name} 是類庫名稱的占位符(例如 MyComponentsLibrary),{Path to file} 是 wwwroot 文件夾下的文件路徑。
讓我們使用上面描述的特殊語法來修復我們的圖片路徑。
BlazorLogo.razor
<img src="_content/MyComponentsLibrary/images/blazor_logo.jpg" alt="Blazor Logo"/>
再次運行項目,這次您會注意到圖片按預期顯示了。
我們還可以使用上述特殊語法直接訪問 Razor 類庫中的圖片。例如,下面的代碼片段將使用 BlazorLogo 組件以及 img 標簽顯示 Razor 類庫中的圖片。請注意,Blazor 應用中的 img 標簽使用相同的特殊語法來訪問 MyComponentsLibrary 中的圖片。
Index.razor
<h1>Hello, Blazor!</h1>
<h4>Showing Image from a Component available inside Class Library</h4>
<BlazorLogo></BlazorLogo>
<h4>Showing Image directly from Class Library</h4>
<img src="_content/MyComponentsLibrary/images/blazor_logo.jpg" alt="Blazor Logo" />
再次運行該項目,這次您應該會看到相同的圖片使用了兩種不同的方式顯示兩次。
使用 Razor 類庫中樣式表
我們還可以在 Razor 類庫中添加樣式表,並且 Blazor 應用程序可以使用這些樣式表中定義的樣式。 讓我們在 wwwroot/css 文件夾中添加一個樣式表 components.css。
出於演示目的,讓我們添加一些與 img 標簽相關的樣式。
components.css
img
{
background-color: lightgreen;
padding: 5px;
border: 1px solid black;
}
要在我們的 Blazor 應用程序中包含 components.css 文件,我們可以使用與上面看到的相同的特殊語法。 打開 Blazor Server 應用程序中的 _Host.cshtml 文件,並使用以下 link 標簽將 components.css 文件包含在 head 標簽內。
_Host.cshtml
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
...
<link href="~/_content/MyComponentsLibrary/css/components.css" rel="stylesheet" />
</head>
運行項目,您會發現我們在 components.css 文件中定義的與 img 標簽相關的樣式被應用到了項目中的所有圖片上。
總結
我在本文中介紹了可重用組件的非常基礎的示例,但您可以借此領會到 Razor 類庫的強大功能。開發者可以創建一些又酷又炫的可重用 Blazor 組件庫,這些庫不僅可以為您的項目添加一些高級功能,還可以提升開發速度。許多組件供應商已經開發了一些開源和商業庫,例如 MatBlazor[3]、Radzen[4]、Syncfusion[5] 等。
相關閱讀:
- Blazor Server 和 WebAssembly 應用程序入門指南
- Blazor 組件入門指南
- Blazor 數據綁定開發指南
- Blazor 事件處理開發指南
- Blazor 組件之間使用 EventCallback 進行通信
- Blazor 路由及導航開發指南
- Blazor 模板化組件開發指南
- Blazor Server 應用程序中進行 HTTP 請求
- Blazor WebAssembly 應用程序中進行 HTTP 請求
- Blazor 組件庫開發指南
https://www.ezzylearning.net/tutorial/a-developers-guide-to-blazor-component-libraries A Developer’s Guide To Blazor Component Libraries ↩︎
https://github.com/ezzylearning/BlazorClassLibraryDemo 下載源碼 ↩︎