從 Razor 類別庫 (RCL) 取用 ASP.NET Core Razor 元件

注意

這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前版本,請參閱本文的 .NET 8 版本

元件可以跨專案在 Razor 類別庫 (RCL) 中共用。 在應用程式中包含元件和靜態資產,其來源如下:

  • 方案中的另一個專案。
  • 參考的 .NET 程式庫。
  • NuGet 套件。

就像元件是一般 .NET 型別一樣,RCL 所提供的元件是一般的 .NET 元件。

建立 RCL

  1. 建立新專案。
  2. 在 [建立新專案] 對話方塊中,從 [ASP.NET 核心專案範本] 清單中選取 [Razor 類別庫]。 選取 [下一步] 。
  3. 在 [設定新的專案] 對話方塊中,在 [專案名稱] 欄位中提供專案名稱,或接受預設專案名稱。 本主題中的範例會使用專案名稱 ComponentLibrary。 選取建立
  4. 在 [建立新的 Razor 類別庫] 對話方塊中,選取 [建立]
  5. 將 RCL 新增至方案:
    1. 開啟解決方案。
    2. 在 [方案總管] 中,以滑鼠右鍵按一下方案。 選取 [新增]>[現有專案]
    3. 瀏覽至 RCL 的專案檔。
    4. 選取 RCL 的專案檔 (.csproj)。
  6. 從應用程式新增 RCL 的參考:
    1. 以滑鼠右鍵按一下應用程式專案。 選取 [新增]>[專案參考]
    2. 選取 RCL 專案。 選取 [確定]。

如果在從範本產生 RCL 時選取 [支援頁面和檢視] 核取方塊,以支援頁面和檢視:

  • 使用下列內容將 _Imports.razor 檔案新增至產生 RCL 專案的根目錄,以啟用 Razor 元件製作:

    @using Microsoft.AspNetCore.Components.Web
    
  • 將下列 SupportedPlatform 項目新增至專案檔 (.csproj):

    <ItemGroup>
      <SupportedPlatform Include="browser" />
    </ItemGroup>
    

    如需 SupportedPlatform 項目的詳細資訊,請參閱用戶端瀏覽器相容性分析器一節。

如果在從範本產生 RCL 時選取 [支援頁面和檢視] 核取方塊以支援頁面和檢視,請使用下列內容將 _Imports.razor 檔案新增至產生 RCL 專案的根目錄,以啟用 Razor 元件製作:

@using Microsoft.AspNetCore.Components.Web

從 RCL 取用 Razor 元件

若要從另一個專案的 RCL 取用元件,請使用下列其中一種方法:

  • 使用包含 RCL 命名空間的完整元件類型名稱。
  • 如果 Razor 的 @using 指示詞宣告 RCL 的命名空間,則可以依名稱新增個別元件,而不使用 RCL 的命名空間。 使用下列方法:
    • @using 指示詞新增至個別元件。
    • 在最上層 _Imports.razor 檔案中包含 @using 指示詞,讓程式庫的元件可供整個專案使用。 將指示詞新增至任何層級的 _Imports.razor 檔案,以將命名空間套用至資料夾內的單一元件或元件集。 使用 _Imports.razor 檔案時,個別元件不需要 RCL 命名空間的 @using 指示詞。

在下列範例中,ComponentLibrary 是包含 Component1 元件的 RCL。 Component1 元件是自動新增至從 RCL 專案範本建立的 RCL 範例元件,該範本不是為了支援頁面和檢視而建立。

注意

如果建立 RCL 以支援頁面和檢視,如果您打算遵循本文中的範例,請手動將 Component1 元件及其靜態資產新增至 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

RCL 專案範本中的斜條紋背景影像

若要從程式庫 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> 內容的位置)。

<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 專案範本中的斜條紋背景影像

RCL 的 Component1 範例元件會使用下列背景影像和樣式表。 不需要將這些靜態資產新增至從 RCL 專案範本建立的新 RCL,因為專案範本會自動新增這些資產。

ComponentLibrary RCL 中的 wwwroot/background.png

由 RCL 專案範本新增至程式庫的斜條紋背景影像

ComponentLibrary RCL 中的 wwwroot/styles.css

.my-component {
    border: 2px dashed red;
    padding: 1em;
    margin: 1em 0;
    background-image: url('background.png');
}

若要提供 Component1my-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

Jeep YJ®

將下列 JeepYJ 元件新增至 RCL。

ComponentLibrary RCL 中的 JeepYJ.razor

<h3>ComponentLibrary.JeepYJ</h3>

<p>
    <img alt="Jeep YJ&reg;" 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&reg;" 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 元件:

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,其中預留位置為:

指令碼的相對 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 應用程式 (.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 中,這是元件類別的 IJSObjectReferencemodule 用於呼叫 showPrompt2 函式。 {PATH} 預留位置是元件路徑。

重要

如果您在測試應用程式中使用下列程式碼進行示範,請將 {PATH} 預留位置變更為元件的路徑。 在 Blazor Web 應用程式 (.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)
        {
            await module.DisposeAsync();
        }
    }
}

{PATH}/JsCollocation2.razor.js

export function showPrompt2(message) {
  return prompt(message, 'Type your name here');
}

對於 Razor 類別庫 (RCL) 所提供的指令碼或模組,會使用下列路徑:

_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js

  • {PACKAGE ID} 預留位置是 RCL 的封裝識別碼 (或應用程式所參考類別庫的程式庫名稱)。
  • {PATH} 預留位置是元件路徑。 如果 Razor 元件位於 RCL 的根目錄,則不包含路徑區段。
  • {COMPONENT} 預留位置是元件名稱。
  • {EXTENSION} 預留位置符合元件的副檔名 (可以是 razorcshtml)。

在以下 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啟用互動式 WebAssembly 元件、Blazor WebAssembly 應用程式和 RCL 專案的 Web Apps,透過使用 SupportedPlatform MSBuild 項目將 browser 新增為支援的平台,自動啟用瀏覽器相容性檢查。 程式庫開發人員可以手動將 SupportedPlatform 項目新增至程式庫的專案檔,以啟用此功能:

<ItemGroup>
  <SupportedPlatform Include="browser" />
</ItemGroup>

製作程式庫時,請藉由指定 browserUnsupportedOSPlatformAttribute,指出瀏覽器中不支援特定 API:

using System.Runtime.Versioning;

...

[UnsupportedOSPlatform("browser")]
private static string GetLoggingDirectory()
{
    ...
}

如需詳細資訊,請參閱標註特定平台上不支援的 API (dotnet/designs GitHub 存放庫)。

JavaScript 模組中的 JavaScript 隔離

Blazor 可在標準 JavaScript 模組中啟用 JavaScript 隔離。 JavaScript 隔離提供下列優點:

  • 已匯入的 JavaScript 不再會產生全域命名空間問題。
  • 不需要程式庫和元件的取用者手動匯入相關的 JavaScript。

如需詳細資訊,請參閱從 ASP.NET Core Blazor 中的 .NET 方法呼叫 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。

商標

JeepJeep YJFCA US LLC (Stellantis NV) 的註冊商標。

其他資源