本篇文章同步發表於 個人部落格 Jim's Blog
在第四章元件的介紹中,提到元件可重複使用,但是如果元件的內容都固定了要怎麼重複使用呢?
寫程式的大家都知道,看到重複的邏輯時應當要抽離成方法(Method),當一段重複的邏輯要重構成方法時,要做的步驟如下:
元件也是一樣的,一個可重複使用的元件,可能會有一些地方需要變化,這時候就需要使用到參數來處理,畢竟參數本身就是值的不確定性,今天讓我們一起來認識 Blazor 元件中的參數該如何使用
我們以一個簡單的元件範例來做說明,這是Bootstrap Card,有10張這樣的卡片要製作,但是不一樣的地方只有內容,此時我們就可以把這份 Card 做成 Card.razor
<div class="card">
<div class="card-header">
@CardHeader
</div>
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>@Text</p>
<footer class="blockquote-footer">@Author</footer>
</blockquote>
</div>
</div>
@code {
[Parameter]
public string CardHeader{ get; set; }
[Parameter]
public string Text{ get; set; }
[Parameter]
public string Author { get; set; }
}
在元件中,替公開屬性上加入 Parameter Attribute,就會被識別為參數
完成這個 Card.razor 之後,在另一個元件中可以呼叫它,看起來會像是這樣
@page "/ParamterSample"
<h3>ParamterSample</h3>
<Card
CardHeader="第一則"
Text="寫程式時要保持這種心態:就好像將來要維護你這些程式的人是一位殘暴的精神病患者,而且他知道你住在哪"
Author="Martin Golding">
</Card>
<Card
CardHeader="第二則"
Text="這不是個 bug——這一個未註明的功能特徵"
Author="Anonymous">
</Card>
在引用其他元件時需注意,元件的參數內容如果需要從C#內指派,要在被指派的成員前面加上
@
符號<Card CardHeader="@Header" Text="@Text" Author="@Author"></Card>
[Parameter]
public string Text{ get; set; }
如果要操作參數的資料,另外做屬性或方法是比較好的做法
<Card CardHeader="@await GetHeader" </Card>
// 'await' 運算子只能在非同步方法中使用。
// 請考慮使用 'async' 修飾詞標記這個方法,並將其傳回類型變更為 'Task'。
如果要從非同步的作業中取值,可以使用元件生命週期的OnInitializedAsync,寫起來會像是這樣
<Card CardHeader="@title" </Card>
@code{
private string? title;
protected override async Task OnInitializedAsync()
{
title = await GetHeader();
}
}
生命週期也會專門做文章跟大家探討
<Card CardHeader="我的卡片 @(Card.Title)" </Card>
// Component attributes do not support complex content (mixed C# and markup).
如果要做字串連接,可以在下方code區域處理字串後在使用
父元件 Parent.razor
@page "/Parent"
<h3>父子元件參數傳遞</h3>
<h4>父元件</h4>
<input class="form-control" @bind="ParentMessage">
<Child></Child>
@code {
[Parameter]
public string ParentMessage{ get; set; }
}
子元件 Child.razor
<h4>子元件</h4>
<input value="@ChildMessage" class="form-control">
@code {
[Parameter]
public string ChildMessage{ get; set; }
}
打開父元件的頁面是長這樣
要在對父元件的Input
輸入時,將參數傳給子元件,做法如下
EventCallback<T>
,T 是子元件內部接收外部參數的型別並且命名為Changed
。父元件的 ParentMessage
參數,要傳遞到子元件內的 ChildMessage
參數,所以EventCallback
的 <T>
會是ChildMessage
的型別也就是string
,EventCallback
的參數名稱 必須 是子元件參數名稱加上Changed
,寫起來會像是這樣
[Parameter]
public EventCallback<string> ChildMessageChanged { get; set; }
<Child @bind-ChileMessage="ParentMessage"></Child>
如此就實現父傳子的功能
如果命名不想要受到 慣例(Convention) 的影響,只要將父元件的 bind 拆開處理即可
在子元件內加入事件,對 Input
輸入完成後,透過事件去更新子元件的欄位,去呼叫 ChildMessageChanged
,這樣的做法被稱為 鏈式綁定(Chained bind)
private async Task UpdateMessageFromChild(ChangeEventArgs args)
{
ChildMessage = args.Value.ToString();
await ChildMessageChanged.InvokeAsync(ChildMessage);
}
我們了解了元件該怎麼設定參數,還有非常重要的參數傳遞的方法,下一章介紹元件的一生是怎麼樣過的會,來了解它的生命中會遇到什麼事件