Share via


在 JavaScript 應用程式和 SPA 架構中使用 Razor 元件

注意

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

重要

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

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

此文章介紹如何從 JavaScript 轉譯 Razor 元件、使用 Blazor 自訂元素,以及產生 Angular 和 React 元件。

Angular 範例應用程式

從 JavaScript 轉譯 Razor 元件

Razor 元件可以從現有 JS 應用程式的 JavaScript (JS) 進行動態轉譯。

此節中的範例透過 JS 將下列 Razor 元件轉譯成頁面。

Quote.razor

<div class="m-5 p-5">
    <h2>Quote</h2>
    <p>@Text</p>
</div>

@code {
    [Parameter]
    public string? Text { get; set; }
}

Program 檔案中,新增元件位置的命名空間

針對應用程式的根元件集合呼叫 RegisterForJavaScript,以將 Razor 元件註冊為用於 JS 轉譯的根元件。

RegisterForJavaScript 包含一個多載,該多載可接受執行初始化邏輯 (javaScriptInitializer) 之 JS 函式的名稱。 在 Blazor 應用程式啟動之後以及任何元件轉譯之前,每次元件註冊時都會立即呼叫 JS 函式一次。 此函式可用於與 JS 技術整合,例如 HTML 自訂元素或以 JS 為基礎的 SPA 架構。

您可以建立一或多個初始設定式函式,並由不同的元件註冊呼叫。 典型的使用案例是針對多個元件重複使用相同的初始設定式函式,如果初始設定式函式正在設定整合自訂元素或其他以 JS 為基礎的 SPA 架構,則這是預期會發生的情況。

重要

請勿將 RegisterForJavaScriptjavaScriptInitializer 參數與 JavaScript 初始設定式混淆。 該參數名稱和 JS 初始設定式功能的名稱恰巧相同。

下列範例會示範上述以 "quote" 作為識別碼之 Quote 元件的動態註冊。

  • 在 Blazor Web 應用程式中,修改伺服器端 Program 檔案中對 AddInteractiveServerComponents 的呼叫:

    builder.Services.AddRazorComponents()
        .AddInteractiveServerComponents(options =>
        {
            options.RootComponents.RegisterForJavaScript<Quote>(identifier: "quote",
              javaScriptInitializer: "initializeComponent");
        });
    
  • 在 Blazor Server 應用程式中,修改 Program 檔案中對 AddServerSideBlazor 的呼叫:

    builder.Services.AddServerSideBlazor(options =>
    {
        options.RootComponents.RegisterForJavaScript<Quote>(identifier: "quote", 
            javaScriptInitializer: "initializeComponent");
    });
    
  • 在 Blazor WebAssembly 應用程式中,呼叫用戶端 Program 檔案中 RootComponents 上的 RegisterForJavaScript

    builder.RootComponents.RegisterForJavaScript<Quote>(identifier: "quote", 
        javaScriptInitializer: "initializeComponent");
    

使用 nameparameters 函式參數將初始設定式函式附加至 window 物件。 為了示範目的,下列 initializeComponent 函式會記錄已註冊元件的名稱和參數。

wwwroot/jsComponentInitializers.js

window.initializeComponent = (name, parameters) => {
  console.log({ name: name, parameters: parameters });
}

使用已註冊的識別碼將元件從 JS 轉譯為容器元素,並視需要傳遞元件參數。

在以下範例中:

  • 呼叫 showQuote 函式時,Quote 元件 ( quote識別碼) 會轉譯為 quoteContainer 元素。
  • 引用字串會傳遞至元件的 Text 參數。

wwwroot/scripts.js

async function showQuote() {
  let targetElement = document.getElementById('quoteContainer');
  await Blazor.rootComponents.add(targetElement, 'quote', 
  {
    text: "Crow: I have my doubts that this movie is actually 'starring' " +
      "anybody. More like, 'camera is generally pointed at.'"
  });
}

在載入 Blazor 指令碼之後,請將上述指令碼載入到 JS 應用程式:

<script src="_framework/{BLAZOR SCRIPT}"></script>
<script src="jsComponentInitializers.js"></script>
<script src="scripts.js"></script>

在上述範例中,{BLAZOR SCRIPT} 預留位置是 Blazor 指令碼。

在 HTML 中,放置目標容器元素 (quoteContainer)。 為了在此節中示範,一個按鈕會藉由呼叫 showQuoteJS 函式來觸發轉譯 Quote 元件:

<button onclick="showQuote()">Show Quote</button>

<div id="quoteContainer"></div>

在轉譯任何元件之前進行初始化時,瀏覽器的開發人員工具主控台會在呼叫 initializeComponent 時記錄 Quote 元件的識別碼 (name) 和參數 (parameters):

Object { name: "quote", parameters: (1) […] }
  name: "quote"
  parameters: Array [ {…} ]
    0: Object { name: "Text", type: "string" }
    length: 1

選取 Show Quote 按鈕時,會轉譯 Quote 元件,並顯示儲存在 Text 中的引用內容:

在瀏覽器中轉譯的 Quote

引用 ©1988-1999 Satellite of Love LLC:《神祕科學戲院 3000》 (Trace Beaulieu (Crow))

注意

rootComponents.add 傳回元件的執行個體。 在執行個體上呼叫 dispose 以釋放它:

const rootComponent = await window.Blazor.rootComponents.add(...);

...

rootComponent.dispose();

上述範例在呼叫 showQuote()JS 函式時以動態方式轉譯根元件。 若要在 Blazor 啟動時將根元件轉譯為容器元素,請使用 JavaScript 初始設定式來轉譯元件,如下列範例所示。

下列範例使用 Quote 元件、Program 檔案中的根元件註冊,以及 jsComponentInitializers.js 的初始化,建置在上述範例的基礎之上。 未使用 showQuote() 函式 (和 script.js 檔案)。

在 HTML 中,放置目標容器元素,以此範例來說是 quoteContainer2

<div id="quoteContainer2"></div>

使用 JavaScript 初始設定式,將根元件新增至目標容器元素。

wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js

針對 Blazor Web 應用程式:

export function afterWebStarted(blazor) {
  let targetElement = document.getElementById('quoteContainer2');
  blazor.rootComponents.add(targetElement, 'quote',
    {
      text: "Crow: I have my doubts that this movie is actually 'starring' " +
          "anybody. More like, 'camera is generally pointed at.'"
    });
}

針對 Blazor Server 或 Blazor WebAssembly 應用程式:

export function afterStarted(blazor) {
  let targetElement = document.getElementById('quoteContainer2');
  blazor.rootComponents.add(targetElement, 'quote',
    {
      text: "Crow: I have my doubts that this movie is actually 'starring' " +
          "anybody. More like, 'camera is generally pointed at.'"
    });
}

注意

若要呼叫 rootComponents.add,請使用 Blazor 啟動事件所提供的 blazor 參數 (小寫 b)。 雖然在使用 Blazor 物件 (大寫 B) 時註冊有效,但建議的方法是使用參數。

如需具有其他功能的進階範例,請參閱 ASP.NET Core 參考來源 (dotnet/aspnetcore GitHub 存放庫) 中的 BasicTestApp 範例:

注意

.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

Blazor 自訂元素

使用 Blazor 自訂元素,從其他 SPA 架構 (例如 Angular 或 React) 動態轉譯 Razor 元件。

Blazor 自訂元素:

  • 使用標準 HTML 介面來實作自訂 HTML 元素。
  • 不需要使用 JavaScript API 手動管理根 Razor 元件的狀態和生命週期。
  • 可用於逐步將 Razor 元件導入以其他 SPA 架構撰寫的現有專案中。

自訂元素不支援子內容範本化元件

元素名稱

根據 HTML 規格,自訂元素標記名稱必須採用烤肉串式命名法:

無效:mycounter
無效:MY-COUNTER
無效:MyCounter
有效:my-counter
有效:my-cool-counter

套件

Microsoft.AspNetCore.Components.CustomElements 的封裝參考新增至應用程式的專案檔。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。

範例元件

下列範例以 Blazor 專案範本中的 Counter 元件為基礎。

Counter.razor

@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Blazor Web 應用程式註冊

請採取下列步驟,將根元件註冊為 Blazor Web 應用程式中的自訂元素。

Microsoft.AspNetCore.Components.Web 命名空間新增至伺服器端 Program 檔案的頂端:

using Microsoft.AspNetCore.Components.Web;

為應用程式的元件新增命名空間。 在下列範例中,應用程式的命名空間是 BlazorSample,元件則位於 Components/Pages 資料夾中:

using BlazorSample.Components.Pages;

修改對 AddInteractiveServerComponents 的呼叫,以在 RootComponents 線路選項上使用 RegisterCustomElement 來指定自訂元素。 下列範例會向自訂 HTML 元素 my-counter 註冊 Counter 元件:

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents(options =>
    {
        options.RootComponents.RegisterCustomElement<Counter>("my-counter");
    });

Blazor Server 註冊

請採取下列步驟,將根元件註冊為 Blazor Server 應用程式中的自訂元素。

Microsoft.AspNetCore.Components.Web 命名空間新增至 Program 檔案的頂端:

using Microsoft.AspNetCore.Components.Web;

為應用程式的元件新增命名空間。 在下列範例中,應用程式的命名空間是 BlazorSample,元件則位於 Pages 資料夾中:

using BlazorSample.Pages;

修改對 AddServerSideBlazor 的呼叫。 在 RootComponents 線路選項上使用 RegisterCustomElement 來指定自訂元素。 下列範例會向自訂 HTML 元素 my-counter 註冊 Counter 元件:

builder.Services.AddServerSideBlazor(options =>
{
    options.RootComponents.RegisterCustomElement<Counter>("my-counter");
});

Blazor WebAssembly 註冊

請採取下列步驟,將根元件註冊為 Blazor WebAssembly 應用程式中的自訂元素。

Microsoft.AspNetCore.Components.Web 命名空間新增至 Program 檔案的頂端:

using Microsoft.AspNetCore.Components.Web;

為應用程式的元件新增命名空間。 在下列範例中,應用程式的命名空間是 BlazorSample,元件則位於 Pages 資料夾中:

using BlazorSample.Pages;

RootComponents 上呼叫 RegisterCustomElement。 下列範例會向自訂 HTML 元素 my-counter 註冊 Counter 元件:

builder.RootComponents.RegisterCustomElement<Counter>("my-counter");

使用已註冊的自訂元素

請搭配使用自訂元素與任何 Web 架構。 例如,上述轉譯應用程式 Counter 元件的 my-counter 自訂 HTML 元素便在具有下列標記的 React 應用程式中使用:

<my-counter></my-counter>

如需如何使用 Blazor 建立自訂元素的完整範例,請參閱參考來源中的 CustomElementsComponent 元件 (部分機器翻譯)。

注意

.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

傳遞參數

將參數以 HTML 屬性或 DOM 元素上的 JavaScript 屬性形式傳遞至 Razor 元件。

下列 Counter 元件會使用 IncrementAmount 參數來設定 Click me 按鈕的遞增量。

Counter.razor

@page "/counter"

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    [Parameter]
    public int IncrementAmount { get; set; } = 1;

    private void IncrementCount()
    {
        currentCount += IncrementAmount;
    }
}

使用自訂元素轉譯 Counter 元件,並將值當做 HTML 屬性傳遞至 IncrementAmount 參數。 屬性名稱採用烤肉串式語法 (increment-amount,而非 IncrementAmount):

<my-counter increment-amount="10"></my-counter>

或者,您可以將參數的值設定為元素物件上的 JavaScript 屬性。 屬性名稱採用駱駝式語法 (incrementAmount 而非 IncrementAmount):

const elem = document.querySelector("my-counter");
elem.incrementAmount = 10;

您可以隨時使用屬性或屬性語法來更新參數值。

支援的參數型別:

  • 使用 JavaScript 屬性語法,您可以傳遞JS可序列化型別的任何物件。
  • 使用 HTML 屬性時,您只能傳遞字串、布林值或數值型別的物件。

有「實驗性」支援可供您使用 Microsoft.AspNetCore.Components.CustomElements NuGet 套件來建置自訂元素。 自訂元素會使用標準 HTML 介面來實作自訂 HTML 元素。

警告

實驗性功能僅供您探索功能的可行性,穩定版內不一定會有此功能。

將根元件註冊為自訂元素:

  • 在 Blazor Server 應用程式中,修改 Program 檔案中對 AddServerSideBlazor 的呼叫,以在 CircuitOptions.RootComponents 上呼叫 RegisterCustomElement

    builder.Services.AddServerSideBlazor(options =>
    {
        options.RootComponents.RegisterCustomElement<Counter>("my-counter");
    });
    

    注意

    上述程式碼範例需要 Program 檔案中應用程式元件的命名空間 (例如,using BlazorSample.Components.Pages;)。

  • 在 Blazor WebAssembly 應用程式中,呼叫 Program 檔案中 WebAssemblyHostBuilder.RootComponents 上的 RegisterCustomElement

    builder.RootComponents.RegisterCustomElement<Counter>("my-counter");
    

    注意

    上述程式碼範例需要 Program 檔案中應用程式元件的命名空間 (例如,using BlazorSample.Components.Pages;)。

在應用程式的 HTML 中,於 Blazor 指令碼標籤「之前」包含下列 <script> 標籤:

<script src="/_content/Microsoft.AspNetCore.Components.CustomElements/BlazorCustomElements.js"></script>

請搭配使用自訂元素與任何 Web 架構。 例如,上述計數器自訂元素便用於具有下列標記的 React 應用程式中:

<my-counter increment-amount={incrementAmount}></my-counter>

警告

自訂元素功能目前僅供實驗、不受支援,且隨時可能會進行變更或移除。 歡迎您針對此特定方法與您的需求是否相符來提供意見反應。

產生 Angular 和 React 元件

針對 Web 架構 (例如 Angular 或 React) 從 Razor 元件產生架構特定的 JavaScript (JS) 元件。 這項功能未隨附於 .NET 中,但從 JS 轉譯 Razor 元件的支援會啟用這項功能。 GitHub 上的 JS 元件產生範例會示範如何從 Razor 元件產生 Angular 和 React 元件。 如需詳細資訊,請參閱 GitHub 範例應用程式的 README.md 檔案。

警告

Angular 和 React 元件功能目前僅供實驗、不受支援,且隨時可能會進行變更或移除。 歡迎您針對此特定方法與您的需求是否相符來提供意見反應。