在 JavaScript 应用和 SPA 框架中使用 Razor 组件
注意
此版本不是本文的最新版本。 对于当前版本,请参阅此文的 .NET 8 版本。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 对于当前版本,请参阅此文的 .NET 8 版本。
本文介绍如何从 JavaScript 呈现 Razor 组件、使用 Blazor 自定义元素,以及生成 Angular 和 React 组件。
注意
建议在将 Razor 组件集成到现有 JavaScript 应用时使用 blazor.server.js
(Blazor Server) 和 blazor.webassembly.js
(Blazor WebAssembly) 脚本,直到将来添加了对 blazor.web.js
(Blazor Web App)脚本的更好支持。 有关详细信息,请参阅 RegisterCustomElement 在 Blazor 8 (dotnet/aspnetcore
#53920) 中停止工作。
Angular 示例应用
- CustomElementsBlazorSample (Blazor Server)(
javiercn/CustomElementsBlazorSample
,分支:blazor-server
):.NET 8 支持 Blazor Server。 若要将此 .NET 7 示例迁移到 .NET 8,请参阅从 ASP.NET Core 7.0 迁移到 8.0。 - CustomElementsBlazorSample (Blazor WebAssembly) (
javiercn/CustomElementsBlazorSample
,分支:blazor-wasm
):若要将此 .NET 7 示例迁移到 .NET 8,请参阅从 ASP.NET Core 7.0 迁移到 8.0。
从 JavaScript 呈现 Razor 组件
可以从 JavaScript (JS) 为现有 JS 应用动态呈现 Razor 组件。
本部分中的示例通过 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 框架的集成,则这是预期的。
重要
不要将 RegisterForJavaScript 的 javaScriptInitializer
参数与 JavaScript 初始值设定项混淆。 参数的名称与 JS 初始值设定项功能的名称碰巧是一样的。
以下示例演示了前面以“quote
”作为标识符的 Quote
组件的动态注册。
在 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");
使用 name
和 parameters
函数参数将初始值设定项函数附加到 window
对象。 出于演示目的,以下 initializeComponent
函数记录已注册组件的名称和参数。
wwwroot/jsComponentInitializers.js
:
window.initializeComponent = (name, parameters) => {
console.log({ name: name, parameters: parameters });
}
使用已注册的标识符将组件从 JS 呈现到容器元素,并根据需要传递组件参数。
如下示例中:
- 调用
showQuote
函数时,Quote
组件(quote
标识符)呈现到quoteContainer
元素中。 - 引号字符串将传递给组件的
Text
参数。
wwwroot/scripts.js
:
window.showQuote = async () => {
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.'"
});
}
const btn = document.querySelector("#showQuoteBtn");
btn.addEventListener("click", showQuote);
加载 Blazor 脚本后,将前面的脚本加载到 JS 应用中:
<script src="_framework/{BLAZOR SCRIPT}"></script>
<script src="jsComponentInitializers.js"></script>
<script src="scripts.js"></script>
在前面的示例中,{BLAZOR SCRIPT}
占位符为 Blazor 脚本。
在 HTML 中,放置目标容器元素 (quoteContainer
)。 在本部分的演示中,调用 showQuote
JS 函数后,一个按钮触发 Quote
组件的呈现:
<button id="showQuoteBtn">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
中存储的引文:
引文来自 ©1988-1999 Satellite of Love LLC:Mystery Science Theater 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
:
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 参考源中的 BasicTestApp
示例(dotnet/aspnetcore
GitHub 存储库):
注意
指向 .NET 参考源的文档链接通常会加载存储库的默认分支,该分支表示针对下一个 .NET 版本的当前开发。 若要为特定版本选择标记,请使用“切换分支或标记”下拉列表。 有关详细信息,请参阅如何选择 ASP.NET Core 源代码的版本标记 (dotnet/AspNetCore.Docs #26205)。
Blazor 自定义元素
使用 Blazor 自定义元素从其他 SPA 框架(如 Angular 或 React)动态呈现 Razor 组件。
Blazor 自定义元素:
- 使用标准 HTML 接口来实现自定义 HTML 元素。
- 无需使用 JavaScript API 手动管理根 Razor 组件的状态和生命周期。
- 可用于逐步将 Razor 组件引入到用其他 SPA 框架编写的现有项目中。
元素名称
根据 HTML 规范,自定义元素标记名称必须采用 kebab 大小写形式:
无效: 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 Server 注册
执行以下步骤,将根组件注册为 Blazor Server 应用中的自定义元素。
将 Microsoft.AspNetCore.Components.Web 命名空间添加到 Program
文件的顶部:
using Microsoft.AspNetCore.Components.Web;
为应用的组件添加命名空间。 在以下示例中,应用的命名空间为 BlazorSample
,且组件位于 Pages
文件夹中:
using BlazorSample.Pages;
修改对 AddServerSideBlazor 的调用。 使用 RootComponents 线路选项上的 RegisterCustomElement 指定自定义元素。 以下示例将 Counter
组件注册到自定义 HTML 元素 my-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。 以下示例将 Counter
组件注册到自定义 HTML 元素 my-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
参数。 属性名称采用 kebab 大小写语法(increment-amount
,不是 IncrementAmount
):
<my-counter increment-amount="10"></my-counter>
或者,可以将参数的值设置为元素对象上的 JavaScript 属性。 属性名称采用驼峰式大小写语法(incrementAmount
,不是 IncrementAmount
):
const elem = document.querySelector("my-counter");
elem.incrementAmount = 10;
可以随时使用特性或属性语法更新参数值。
支持的参数类型:
- 使用 JavaScript 属性语法,可以传递任何 JSON 可序列化类型的对象。
- 使用 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 框架结合使用。 例如,前面的 counter 自定义元素在带有以下标记的 React 应用中使用:
<my-counter increment-amount={incrementAmount}></my-counter>
警告
自定义元素功能目前处于实验阶段,不受支持,并且随时可能更改或删除。 欢迎你就这种特定方法能否满足你的要求提出反馈意见。
生成 Angular 和 React 组件
通过 Razor 组件为 Web 框架生成特定于框架的 JavaScript (JS) 组件,例如 Angular 或 React。 此功能未包含在 .NET 中,但通过支持(即,支持从 JS 呈现 Razor 组件)得以实现。 GitHub 上的JS 组件生成示例演示了如何通过 Razor 组件生成 Angular 和 React 组件。 有关其他信息,请参阅 GitHub 示例应用的 README.md
文件。
警告
Angular 和 React 组件功能目前处于实验阶段,不受支持,并且随时可能更改或删除。 欢迎你就这种特定方法能否满足你的要求提出反馈意见。