Blazor组件通信
组件概述
前提知识:
微软官方文档中关于组件的说明如下:
① 组件 是内置到 .NET程序集
的 .NET C#类
,组件类 通常以Razor标记页
的形式编写。
② Blazor中的 组件 正式称为Razor组件
,非正式地称为Blazor组件
。
③ Razor 是一种语法,用于将HTML标记
与专为提高开发人员工作效率而设计的C#代码
结合在一起。
④ 组件 在内存中以浏览器文档对象模型(DOM)
的形式存在,这种形式被称为呈现树
,用于以灵活高效的方式更新UI。
组件通信
前提知识:
组件参数
组件参数将数据传递给组件,使用组件类中的公共C#属性 [Parameter]特性 进行定义。
代码说明: ParameterChild组件
通过组件参数的方式从ParameterParent组件
接收Title
和Body
的值。
代码示例:(提示:以下代码改编于微软官方文档 ASP.NET Core Razor 组件 - 组件参数)
PanelBody.cs
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
ParameterChild.razor
<h1>This is a child component.</h1>
<div>
<div>@Title</div>
<div style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[Parameter]
public string Title { get; set; }
[Parameter]
public PanelBody Body { get; set; }
}
ParameterParent.razor
@page "/parameter-parent"
<h1>This is a parent component.</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody(){Text = "Set by Parent.", Style = "italic"})" />
级联值和参数
① 级联值和参数提供了一种可将数据沿组件层次结构从祖先组件向下流向任意数量的后代组件的方法。
② 不同于组件参数,级联值和参数不需要对使用数据的每个后代组件分配特性。
③ 级联值和参数还允许组件在组件层次结构中相互协调。
级联参数通过CascadingValue组件和[CascadingParameter]特性来实现:
- CascadingValue组件:用于在组件树种向下传递数据
- [CascadingParameter]特性用于在子组件种接收通过CascadingValue组件传递的数据
常用方式
代码说明:Title
和Body
的参数值沿组件层次结构从ParameterParent组件
向下流动到ParameterChild组件
代码示例:(提示:以下代码改编于微软官方文档 - ASP.NET Core Blazor 级联值和参数)
PanelBody.cs
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
ParameterChild.razor
<h1>This is a child component.</h1>
<div>
<div>@Title</div>
<div style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[CascadingParameter(Name = "ChildTitle")]
public string Title { get; set; }
[CascadingParameter(Name = "ChildBody")]
public PanelBody Body { get; set; }
}
ParameterParent.razor
@page "/parameter-parent"
<h1>This is a parent component.</h1>
<CascadingValue Value="Set by Parent" Name="ChildTitle">
<CascadingValue Value="@Body" Name="ChildBody">
<ParameterChild />
</CascadingValue>
</CascadingValue>
@{
public PanelBody Body{ get; set; } = new PanelBody(){
Text = "Set by Parent",
Style = "italic"
}
}
跨组件层次结构传递数据
前提知识:
代码说明:父组件设置子组件的内容
代码示例:(提示:以下代码改编于微软官方文档 - ASP.NET Core Razor 组件 - 子内容呈现片段)
ChildComponent.cs
<div>
@ChildContent
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
ParentComponent.cs
<ChildComponent>
<p>在父组件设置子组件的内容<p>
</ChildComponent>
代码说明:在IndexPage页中展示Tab页集合
代码示例:(提示:以下代码改编于微软官方文档 - ASP.NET Core Blazor 级联值和参数)
IndexPage.razor
在IndexPage页中显示三个Tab页。其中,TabSet用于组织和呈现Tab组件,Tab组件用于显示Tab页内容。
@page "/index_page"
<h3>级联参数</h3>
<TabSet>
<Tab Title="First tab">
<p>The first tab!</p>
</Tab>
<Tab Title="Second tab">
<p>The second tab!</p>
</Tab>
<Tab Title="Third tab">
<p>The third tab!</p>
</Tab>
</TabSet>
TabSet.razor
其中,TabSet组件通过 <CascadingValue Value="this">
将自身的实例作为参数传递给子组件。
注:为什么组件也可以作为参数传递呢?因为组件
本质上是以类
的形式存在。
<CascadingValue Value="this">
<ul>
@ChildContent
</ul>
</CascadingValue>
<div>
@ActiveTab?.ChildContent
</div>
@code {
[Parameter]
public RenderFragment? ChildContent{ get; set; }
public Tab? ActiveTab{ get; private set; }
public void AddTab(Tab tab)
{
if (ActiveTab is null)
{
SetActiveTab(tab);
}
}
public void SetActiveTab(Tab tab)
{
if (ActiveTab != tab)
{
ActiveTab = tab;
StateHasChanged();
}
}
}
Tab.razor
<li>
<a @onclick="ActivateTab" class="nav-link @TitleCssClass" role="button">
@Title
</a>
</li>
@code {
[CascadingParameter]
public TabSet? ContainerTabSet{ get; set; }
[Parameter]
public string? Title{ get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
public string? TitleCssClass => ContainerTabSet?.ActiveTab == this ? "active" : null;
protected override void OnInitialized()
{
ContainerTabSet?.AddTab(this);
}
public void ActivateTab()
{
ContainerTabSet?.SetActiveTab(this);
}
}
事件处理
① 嵌套组件的常见方案是在发生子组件事件时,在父组件中执行某个方法。
② EventCallback是一种用于处理事件的标准机制,它允许子组件触发事件并将数据传递回父组件。
③ 通过EventCallback,可以定义一个委托,当事件发生时,父组件中的相应方法会被调用,从而实现组件间的交互和数据传递。
前提知识:
代码说明:子组件从父组件接收EventCallback委托,设置子组件按钮的onclick事件处理程序
代码示例:(提示:以下代码改编于微软官方文档 - ASP.NET Core Blazor 事件处理 - EventCallback)
ChildComponent.razor
<div>
<button @onclick = "OnClickCallback">
Trigger a Parent component method
</button>
</div>
@code{
[Parameter]
public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
ParentComponent.razor
@page "/parent_page"
<ChildComponent OnClickCallback="ShowMessage" />
<p>@_msg</p>
@code{
private string? _msg;
private void ShowMessage(MouseEventArgs e)
{
_msg = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})"
}
}
参考文章
-
ASP.NET Core Razor 组件:
https://learn.microsoft.com/zh-cn/aspnet/core/blazor/components/?view=aspnetcore-6.0#component-parameters -
ASP.NET Core Blazor 事件处理:
https://learn.microsoft.com/zh-cn/aspnet/core/blazor/components/event-handling?view=aspnetcore-6.0
文章声明
- 内容准确性:我会尽力确保所分享信息的准确性和可靠性,但由于个人知识有限,难免会有疏漏或错误。如果您在阅读过程中发现任何问题,请不吝赐教,我将及时更正。