2. 使用Blazor中的模板功能
1 概述
可以使用参数将数据传递到组件中。 参数定义组件的公共 API。 使用参数将数据传递到组件的语法与在标准 HTML 元素上定义属性相同,即使用键值对。key 是参数名称,value 是您希望传递给组件的数据。
2 生命周期
常用的生命周期为
- OnInitialized/OnInitializedAsync:仅仅运行一次
- OnParametersSet/OnParametersSetAsync:每次参数变化时执行
- OnAfterRender/OnAfterRenderAsync:主要用于执行JavaScript和其他的DOM操作
![image]()
3 父子组件
- 传参
父组件->子组件:使用组件普通参数
子组件->父组件:使用组件事件参数
3.1 父传子
3.1.1 在Home文件夹下创建TrialDetails组件
- IsOpen属性用于侧边栏的显示
<div class="offcanvas @(IsOpen ? "show" : "") offcanvas-end" tabindex="-1" id="trailDetail" aria-labelledby="trailDetailLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasLabel">Trail Detail</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body p-0">
@if (SelectedTrail is not null)
{
<div class="card shadow p-0">
<img src="@SelectedTrail.Image" class="card-img-top" alt="@SelectedTrail.Name">
<div class="card-body">
@* 标题 *@
<h5 class="card-tiele">@SelectedTrail.Name</h5>
@* 位置 *@
<h6 class="card-subtitle mb-5 text-muted">
<span class="bi bi-geo">@SelectedTrail.Location</span>
</h6>
@* 描述 *@
<div class="d-flex justify-content-between">
@* 时间 *@
<span>
<span class="bi bi-clock mr-2"></span>
@SelectedTrail.TimeFormatted
</span>
@* 路程 *@
<span>
<span class="bi bi-infinity mr-2"></span>
@SelectedTrail.Length km
</span>
</div>
@* 详情介绍 *@
<p class="mt-4">@SelectedTrail.Description</p>
</div>
</div>
}
</div>
</div>
@code {
[Parameter,EditorRequired]
public Trail? SelectedTrail { get; set; }
[Parameter,EditorRequired]
public bool IsOpen { get; set; }
}
3.2 子传父
3.2.1 在TrailCard组件中添加事件
我们需要在Home页面中的TrailCard组件中将数据传出来作为选择的Trail,所以需要在TrailCard中定义事件。
注意:
Blazor 中的事件不是 .NET 意义上的真实事件; 他们只是代表。 这适
用于 Blazor 的内置 DOM 事件系统和开发人员使用组件参数定义的事件。这
也意味着在任何给定时间,任何给定事件只能有一个处理程序。
我们可以使用名为 EventCallback 的 TrailCard 上的不同类型来定义事件。通过对事件使用此类型,Blazor 将自动在处理事件的组件上调用 StateHasChanged,无需手动调用它。
<div class="col-3 card shadow m-5 p-0">
<img src="@Trail.Image" class="card-img-top" alt="@Trail.Name">
<div class="card-body">
@* 标题 *@
<h5 class="card-tiele">@Trail.Name</h5>
@* 位置 *@
<h6 class="card-subtitle mb-5 text-muted">
<span class="bi bi-geo">@Trail.Location</span>
</h6>
@* 描述 *@
<div class="d-flex justify-content-between">
@* 时间 *@
<span>
<span class="bi bi-clock mr-2"></span>
@Trail.TimeFormatted
</span>
@* 路程 *@
<span>
<span class="bi bi-infinity mr-2"></span>
@Trail.Length km
</span>
</div>
@* 采用EventCallback后,null检测不再需要。同时支持异步回调。 *@
<button class="btn btn-primary" title="View" @onclick="@(() => OnSelected.InvokeAsync(Trail))">
<i class="bi bi-binoculars"></i>
</button>
</div>
</div>
@code
{
[Parameter, EditorRequired] public Trail Trail { get; set; }
[Parameter,EditorRequired]
public EventCallback<Trail> OnSelected { get; set; }
}
3.2.2 在Home页面中触发事件
为了关闭侧边栏,这里添加了一个遮罩层
@page "/"
@inject HttpClient Http
<PageTitle>Blazing Trails</PageTitle>
@if (_trails == null)
{
<p>Loading...</p>
}
else
{
<button class="btn btn-primary" type="button"
data-bs-toggle="offcanvas"
data-bs-target="#trailDetail"
aria-controls="trailDetail">
Button with data-bs-target
</button>
<TrailDetails SelectedTrail="_selectedTrail" IsOpen="_isDetailOpen"></TrailDetails>
<div class="container">
<div class="row">
@foreach (var trail in _trails)
{
<TrailCard Trail="trail" OnSelected="HandelTrailSelected" />
}
</div>
</div>
}
@if (_isDetailOpen)
{
<div class="offcanvas-backdrop fade show"
@onclick="CloseSidebar"></div>
}
@code {
private IEnumerable<Trail>? _trails;
private Trail? _selectedTrail;
private bool _isDetailOpen = false;
protected override async Task OnInitializedAsync()
{
try
{
_trails = await Http
.GetFromJsonAsync<IEnumerable<Trail>>
("trails/trail-data.json");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"There was a problem loading trail data: {ex.Message}");
}
}
private void HandelTrailSelected(Trail trail)
{
_selectedTrail = trail;
_isDetailOpen =!_isDetailOpen;
}
private void CloseSidebar()
{
_isDetailOpen=false;
}
}
3.2.3 在TrailDetials中完善Close按钮
- 添加OnClosed事件用于在Home页面中触发关闭方法。
<button type="button" class="btn-close" @onclick="@(()=>OnClosed.InvokeAsync())"></button>
- 在Home页面中触发
<TrailDetails SelectedTrail="_selectedTrail" IsOpen="_isDetailOpen" OnClosed="CloseSidebar"></TrailDetails>
3.3 最终效果


浙公网安备 33010602011771号