從 Razor 類別庫 (RCL) 取用 ASP.NET Core Razor 元件
注意
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
元件可以跨專案在 Razor 類別庫 (RCL) 中共用。 在應用程式中包含元件和靜態資產,其來源如下:
- 方案中的另一個專案。
- 參考的 .NET 程式庫。
- NuGet 套件。
就像元件是一般 .NET 型別一樣,RCL 所提供的元件是一般的 .NET 元件。
建立 RCL
- 建立新專案。
- 在 [建立新專案] 對話方塊中,從 [ASP.NET 核心專案範本] 清單中選取 [Razor 類別庫]。 選取 [下一步]。
- 在 [設定新專案] 對話方塊中,於 [專案名稱] 欄位中提供專案名稱。 本主題中的範例會使用專案名稱
ComponentLibrary
。 選取 [下一步]。 - 在 Additional information 對話方塊中,請勿選擇 Support pages and views。 選取 建立。
- 將 RCL 新增至方案:
- 開啟解決方案。
- 在 [方案總管] 中,以滑鼠右鍵按一下方案。 選取 [新增]>[現有專案]。
- 瀏覽至 RCL 的專案檔。
- 選取 RCL 的專案檔 (
.csproj
)。
- 從應用程式新增 RCL 的參考:
- 以滑鼠右鍵按一下應用程式專案。 選取 [新增]>[專案參考]。
- 選取 RCL 專案。 選取 [確定]。
從 RCL 取用 Razor 元件
若要從另一個專案的 RCL 取用元件,請使用下列其中一種方法:
- 使用包含 RCL 命名空間的完整元件類型名稱。
- 如果 Razor 的
@using
指示詞宣告 RCL 的命名空間,則可以依名稱新增個別元件,而不使用 RCL 的命名空間。 使用下列方法:- 將
@using
指示詞新增至個別元件。 - 在最上層
_Imports.razor
檔案中包含@using
指示詞,讓程式庫的元件可供整個專案使用。 將指示詞新增至任何層級的_Imports.razor
檔案,以將命名空間套用至資料夾內的單一元件或元件集。 使用_Imports.razor
檔案時,個別元件不需要 RCL 命名空間的@using
指示詞。
- 將
在下列範例中,ComponentLibrary
是包含 Component1
元件的 RCL。 Component1
元件是自動新增至從 RCL 專案範本建立的 RCL 範例元件,該範本不是為了支援頁面和檢視而建立。
在 ComponentLibrary
RCL 中的 Component1.razor
:
<div class="my-component">
This component is defined in the <strong>ComponentLibrary</strong> package.
</div>
在取用 RCL 的應用程式中,使用其命名空間來參考 Component1
元件,如下列範例所示。
ConsumeComponent1.razor
:
@page "/consume-component-1"
<h1>Consume component (full namespace example)</h1>
<ComponentLibrary.Component1 />
或者,新增 @using
指示詞並使用不含其命名空間的元件。 下列 @using
指示詞也可以出現任何 _Imports.razor
檔案中或上方目前資料夾中。
ConsumeComponent2.razor
:
@page "/consume-component-2"
@using ComponentLibrary
<h1>Consume component (<code>@@using</code> example)</h1>
<Component1 />
對於使用 CSS 隔離的程式庫元件,元件樣式會自動提供給取用的應用程式使用。 不需要在取用程式庫的應用程式中手動連結或匯入程式庫的個別元件樣式表或其配套 CSS 檔案。 應用程式會使用 CSS 匯入來參考 RCL 的配套樣式。 配套樣式不會發佈為取用程式庫應用程式的靜態 Web 資產。 針對名為 ClassLib
的類別庫,以及具有 BlazorSample.styles.css
樣式表的 Blazor 應用程式,RCL 的樣式表會在組建時間自動匯入應用程式樣式表頂端:
@import '_content/ClassLib/ClassLib.bundle.scp.css';
針對上述範例,Component1
的樣式表 (Component1.razor.css
) 會自動配套。
在 ComponentLibrary
RCL 中的 Component1.razor.css
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
背景影像也包含在 RCL 專案範本中,且位於 RCL 的 wwwroot
資料夾中。
在 ComponentLibrary
RCL 中的 wwwroot/background.png
:
若要從程式庫 wwwroot
資料夾中的樣式表提供其他程式庫的元件樣式,請將樣式表 <link>
標籤新增至 RCL 的取用者,如下一個範例所示。
重要
一般而言,程式庫元件會使用 CSS 隔離 來組合並提供元件樣式。 依賴 CSS 隔離的元件樣式會自動提供給使用 RCL 的應用程式。 不需要在取用程式庫的應用程式中手動連結或匯入程式庫的個別元件樣式表或其配套 CSS 檔案。 下列範例是針對在 CSS 隔離之外提供全域樣式表,這通常不需要取用 RCL 的一般應用程式。
下一個範例會使用下列背景影像。 如果您實作本節所示的範例,請以滑鼠右鍵按一下影像,將它儲存在本機。
wwwroot/extra-background.png
在 RCL 中 ComponentLibrary
:
使用 extra-style
類別將新的樣式表新增至 RCL。
在 ComponentLibrary
RCL 中的 wwwroot/additionalStyles.css
:
.extra-style {
border: 2px dashed blue;
padding: 1em;
margin: 1em 0;
background-image: url('extra-background.png');
}
將元件新增至使用 extra-style
類別的 RCL。
在 ExtraStyles.razor
RCL 中 的 ComponentLibrary
:
<div class="extra-style">
<p>
This component is defined in the <strong>ComponentLibrary</strong> package.
</p>
</div>
將頁面新增至使用 RCL ExtraStyles
元件的應用程式。
ConsumeComponent3.razor
:
@page "/consume-component-3"
@using ComponentLibrary
<h1>Consume component (<code>additionalStyles.css</code> example)</h1>
<ExtraStyles />
連結至應用程式的 <head>
標記中程式庫的樣式表 (<head>
內容的位置):
Blazor Web App:
<link href="@Assets["_content/ComponentLibrary/additionalStyles.css"]" rel="stylesheet">
獨立 Blazor WebAssembly 應用程式:
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
<link href="_content/ComponentLibrary/additionalStyles.css" rel="stylesheet">
對於使用 CSS 隔離的程式庫元件,元件樣式會自動提供給取用的應用程式使用。 不需要在取用程式庫的應用程式中手動連結或匯入程式庫的個別元件樣式表或其配套 CSS 檔案。 應用程式會使用 CSS 匯入來參考 RCL 的配套樣式。 配套樣式不會發佈為取用程式庫應用程式的靜態 Web 資產。 針對名為 ClassLib
的類別庫,以及具有 BlazorSample.styles.css
樣式表的 Blazor 應用程式,RCL 的樣式表會在組建時間自動匯入應用程式樣式表頂端:
@import '_content/ClassLib/ClassLib.bundle.scp.css';
針對上述範例,Component1
的樣式表 (Component1.razor.css
) 會自動配套。
在 ComponentLibrary
RCL 中的 Component1.razor.css
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
背景影像也包含在 RCL 專案範本中,且位於 RCL 的 wwwroot
資料夾中。
在 ComponentLibrary
RCL 中的 wwwroot/background.png
:
RCL 的 Component1
範例元件會使用下列背景影像和樣式表。 不需要將這些靜態資產新增至從 RCL 專案範本建立的新 RCL,因為專案範本會自動新增這些資產。
在 ComponentLibrary
RCL 中的 wwwroot/background.png
:
在 ComponentLibrary
RCL 中的 wwwroot/styles.css
:
.my-component {
border: 2px dashed red;
padding: 1em;
margin: 1em 0;
background-image: url('background.png');
}
若要提供 Component1
的 my-component
CSS 類別,請連結到應用程式 <head>
標記中程式庫的樣式表 (<head>
內容的位置):
<link href="_content/ComponentLibrary/styles.css" rel="stylesheet" />
從 RCL 提供可路由的元件
若要讓 RCL 中可路由的元件可供直接要求使用,RCL 的組件必須向應用程式的路由器公開。
開啟應用程式的 App
元件 (App.razor
)。 將 Assembly 集合指派給 Router 元件的 AdditionalAssemblies 參數,以包含 RCL 的組件。 在下列範例中,ComponentLibrary.Component1
元件用於探索 RCL 的組件。
AdditionalAssemblies="new[] { typeof(ComponentLibrary.Component1).Assembly }"
如需詳細資訊,請參閱 ASP.NET Core Blazor 路由和瀏覽。
在 wwwroot
資料夾中建立具有靜態資產的 RCL
任何取用程式庫的應用程式都可以使用 RCL 的靜態資產。
將靜態資產放在 RCL 的 wwwroot
資料夾中,並在應用程式中參考具有下列路徑的靜態資產:_content/{PACKAGE ID}/{PATH AND FILE NAME}
。 {PACKAGE ID}
預留位置是程式庫的封裝識別碼。 如果未在專案檔中指定 <PackageId>
,則封裝識別碼預設為專案的組件名稱。 {PATH AND FILE NAME}
預留位置是 wwwroot
下的路徑和檔案名稱。 此路徑格式也會用於應用程式中新增至 RCL 的 NuGet 套件所提供的靜態資產。
下列範例示範如何使用 RCL 靜態資產搭配名為 ComponentLibrary
的 RCL,以及取用 RCL 的 Blazor 應用程式。 應用程式具有 ComponentLibrary
RCL 的專案參考。
本節範例會使用下列 Jeep® 影像。 如果您實作本節所示的範例,請以滑鼠右鍵按一下影像,將它儲存在本機。
wwwroot/jeep-yj.png
在 RCL 中 ComponentLibrary
:
將下列 JeepYJ
元件新增至 RCL。
在 ComponentLibrary
RCL 中的 JeepYJ.razor
:
<h3>ComponentLibrary.JeepYJ</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
將下列 Jeep
元件新增至取用 ComponentLibrary
RCL 的應用程式。 Jeep
元件使用:
- 來自
ComponentLibrary
RCL 資料夾的wwwroot
Jeep YJ® 影像。 - 來自 RCL 的
JeepYJ
元件。
Jeep.razor
:
@page "/jeep"
@using ComponentLibrary
<div style="float:left;margin-right:10px">
<h3>Direct use</h3>
<p>
<img alt="Jeep YJ®" src="_content/ComponentLibrary/jeep-yj.png" />
</p>
</div>
<JeepYJ />
<p>
<em>Jeep</em> and <em>Jeep YJ</em> are registered trademarks of
<a href="https://www.stellantis.com">FCA US LLC (Stellantis NV)</a>.
</p>
轉譯的 Jeep
元件:
如需詳細資訊,請參閱 ASP.NET Core 類別庫中的可重複使用 Razor UI。
使用與元件共置的 JavaScript 檔案建立 RCL
將 JavaScript (JS) 檔案集合起來用於 Razor 元件,是組織應用程式中指令碼的便利方式。
Blazor 應用程式的 Razor 元件會使用 .razor.js
副檔名來共置 JS 檔案,並使用專案中檔案的路徑來公開尋址:
{PATH}/{COMPONENT}.razor.js
{PATH}
預留位置是元件路徑。{COMPONENT}
預留位置是元件。
發佈應用程式時,架構會自動將指令碼移至 Web 根目錄。 指令碼會移至 bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js
,其中預留位置為:
{TARGET FRAMEWORK MONIKER}
是目標 Framework Moniker (TFM)。{PATH}
是元件路徑。{COMPONENT}
是元件名稱。
指令碼的相對 URL 不需要變更,因為 Blazor 會為您將 JS 檔案放在已發佈的靜態資產中。
本節和下列範例主要著重於說明 JS 檔案集合。 第一個範例示範具有一般 JS 函式的共置 JS 檔案。 第二個範例示範如何使用模組來載入函式,這是大部分生產應用程序的建議方法。 從 .NET 呼叫 JS 完全涵蓋於在 ASP.NET Core Blazor 中從 .NET 方法呼叫 JavaScript 函式,其中還以其他範例進一步說明 BlazorJS API。 第二個範例中的元件處置則涵蓋於 ASP.NET Core Razor 元件生命週期中。
下列 JsCollocation1
元件會透過 HeadContent
元件 載入指令碼,並使用 IJSRuntime.InvokeAsync 呼叫 JS 函式。 {PATH}
預留位置是元件路徑。
重要
如果您在測試應用程式中使用下列程式碼進行示範,請將 {PATH}
預留位置變更為元件的路徑 (例如:.NET 8 或更新版本中的 Components/Pages
或 .NET 7 或更早版本中的 Pages
)。 在 Blazor Web App (.NET 8 或更新版本) 中,元件需要全域套用至應用程式或元件定義的互動式轉譯模式。
在 Blazor 指令碼後面新增下列指令碼 (Blazor 啟動指令碼的位置):
<script src="{PATH}/JsCollocation1.razor.js"></script>
JsCollocation1
元件 ({PATH}/JsCollocation1.razor
):
@page "/js-collocation-1"
@inject IJSRuntime JS
<PageTitle>JS Collocation 1</PageTitle>
<h1>JS Collocation Example 1</h1>
<button @onclick="ShowPrompt">Call showPrompt1</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private string? result;
public async void ShowPrompt()
{
result = await JS.InvokeAsync<string>(
"showPrompt1", "What's your name?");
StateHasChanged();
}
}
共置的 JS 檔案會放在 JsCollocation1
元件檔案旁邊,其檔名為 JsCollocation1.razor.js
。 在 JsCollocation1
元件中,指令碼會於共置檔案的路徑參考。 在下列範例中,showPrompt1
函式會接受來自 Window prompt()
的使用者名稱,並將它傳回給 JsCollocation1
元件以供顯示。
{PATH}/JsCollocation1.razor.js
:
function showPrompt1(message) {
return prompt(message, 'Type your name here');
}
不建議在生產應用程式中普遍使用前述方法,因為此方法會用全域函式污染用戶端。 較適合生產應用程式的方法是使用 JS 模組。 相同的一般準則適用於從共置 JS 檔案載入 JS 模組,如下一個範例所示。
下列 JsCollocation2
元件的 OnAfterRenderAsync
方法會將 JS 模組載入 module
中,這是元件類別的 IJSObjectReference。 module
用於呼叫 showPrompt2
函式。 {PATH}
預留位置是元件路徑。
重要
如果您在測試應用程式中使用下列程式碼進行示範,請將 {PATH}
預留位置變更為元件的路徑。 在 Blazor Web App (.NET 8 或更新版本) 中,元件需要全域套用至應用程式或元件定義的互動式轉譯模式。
JsCollocation2
元件 ({PATH}/JsCollocation2.razor
):
@page "/js-collocation-2"
@implements IAsyncDisposable
@inject IJSRuntime JS
<PageTitle>JS Collocation 2</PageTitle>
<h1>JS Collocation Example 2</h1>
<button @onclick="ShowPrompt">Call showPrompt2</button>
@if (!string.IsNullOrEmpty(result))
{
<p>
Hello @result!
</p>
}
@code {
private IJSObjectReference? module;
private string? result;
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
/*
Change the {PATH} placeholder in the next line to the path of
the collocated JS file in the app. Examples:
./Components/Pages/JsCollocation2.razor.js (.NET 8 or later)
./Pages/JsCollocation2.razor.js (.NET 7 or earlier)
*/
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./{PATH}/JsCollocation2.razor.js");
}
}
public async void ShowPrompt()
{
if (module is not null)
{
result = await module.InvokeAsync<string>(
"showPrompt2", "What's your name?");
StateHasChanged();
}
}
async ValueTask IAsyncDisposable.DisposeAsync()
{
if (module is not null)
{
try
{
await module.DisposeAsync();
}
catch (JSDisconnectedException)
{
}
}
}
}
在上述範例中,JSDisconnectedException會在模塊處置期間截獲,以防BlazorSignalR線路遺失。 如果在應用程式中使用Blazor WebAssembly上述程式代碼,則不會SignalR遺失任何連線,因此您可以移除-catch
try
區塊,並保留處置模組的行 ()。await module.DisposeAsync();
如需詳細資訊,請參閱 ASP.NET Core Blazor JavaScript 互通性 (JS Interop)。
{PATH}/JsCollocation2.razor.js
:
export function showPrompt2(message) {
return prompt(message, 'Type your name here');
}
僅在 Blazor 的 JS Interop 機制以 IJSRuntime 介面為基礎時,才支援對 Razor 類別庫 (RCL) 中共置的 JS 使用指令碼和模組。 如果您要實作 JavaScript [JSImport]
/[JSExport]
interop,請參閱 JavaScript Import/Export interop 搭配 ASP.NET Core Blazor。
對於 Razor 類別庫 (RCL) 使用以 IJSRuntime 為基礎的 JS Interop 時提供的指令碼或模組,則會使用下列路徑:
./_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js
- 需要目前目錄 (
./
) 的路徑區段,才能建立 JS 檔案的正確靜態資產路徑。 {PACKAGE ID}
預留位置是 RCL 的封裝識別碼 (或應用程式所參考類別庫的程式庫名稱)。{PATH}
預留位置是元件路徑。 如果 Razor 元件位於 RCL 的根目錄,則不包含路徑區段。{COMPONENT}
預留位置是元件名稱。{EXTENSION}
預留位置符合元件的副檔名 (可以是razor
或cshtml
)。
在以下 Blazor 應用程式範例中:
- RCL 的封裝識別碼為
AppJS
。 - 模組的指令碼會針對
JsCollocation3
元件載入 (JsCollocation3.razor
)。 JsCollocation3
元件位於 RCL 的Components/Pages
資料夾中。
module = await JS.InvokeAsync<IJSObjectReference>("import",
"./_content/AppJS/Components/Pages/JsCollocation3.razor.js");
將元件和靜態資產提供給多個裝載的 Blazor 應用程式
如需詳細資訊,請參閱多個裝載的 ASP.NET Core Blazor WebAssembly 應用程式。
用戶端瀏覽器相容性分析器
用戶端應用程式是以完整的 .NET API 介面區為目標,但 WebAssembly 不支援所有 .NET API,因為瀏覽器沙箱限制。 在 WebAssembly 上執行時,不支援的 API 擲回 PlatformNotSupportedException。 當應用程式使用應用程式的目標平台不支援的 API 時,平台相容性分析器會警告開發人員。 針對用戶端應用程式,這表示檢查瀏覽器是否支援 API。 為相容性分析器標註 .NET Framework API 是一個進行中的流程,因此並非所有 .NET Framework API 目前都會加上標註。
Blazor Web App 啟用互動式 WebAssembly 元件、Blazor WebAssembly 應用程式和 RCL 專案的 Web Apps,透過使用 SupportedPlatform
MSBuild 項目將 browser
新增為支援的平台,自動啟用瀏覽器相容性檢查。 程式庫開發人員可以手動將 SupportedPlatform
項目新增至程式庫的專案檔,以啟用此功能:
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
製作程式庫時,請藉由指定 browser
至 UnsupportedOSPlatformAttribute,指出瀏覽器中不支援特定 API:
using System.Runtime.Versioning;
...
[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
...
}
如需詳細資訊,請參閱標註特定平台上不支援的 API (dotnet/designs
GitHub 存放庫)。
JavaScript 模組中的 JavaScript 隔離
Blazor 可在標準 JavaScript 模組中啟用 JavaScript 隔離。 JavaScript 隔離提供下列優點:
- 已匯入的 JavaScript 不再會產生全域命名空間問題。
- 不需要程式庫和元件的取用者手動匯入相關的 JavaScript。
避免修剪 JavaScript-invokable .NET 方法
執行階段重新連結 會修剪類別執行個體 JavaScript-invokable .NET 方法,除非明確保留它們。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 中從 JavaScript 函式呼叫 .NET 方法。
組建、封裝及傳送至 NuGet
因為包含 Razor 元件的 Razor 類別庫是標準 .NET 程式庫,因此封裝並將它們傳送至 NuGet 與封裝和將任何程式庫傳送至 NuGet 並無不同。 封裝是使用命令殼層中的 dotnet pack
命令來執行:
dotnet pack
使用命令殼層中的 dotnet nuget push
命令,將套件上傳至 NuGet。
商標
Jeep 和 Jeep YJ 是 FCA US LLC (Stellantis NV) 的註冊商標。