Blazor帶我重玩前端(五)
- 2020 年 8 月 31 日
- 筆記
- H::技術潮流之不拘一格
概述
本文主要討論Blazor事件內容,由於blazor事件部分很多,所以會分成上下兩篇,本文為第一篇,後續會有第二篇。
我們可以視組件是一個類,我們先看一下前文所說的Index.Razor頁面生成的C#代碼。
在此,先補充一下該頁面的原始代碼:
1: @page "/"
2: @layout MyLayout
3: <h1>Hello, world!</h1>
4:
5: Welcome to your new app.
6:
7: <SurveyPrompt Title="How is Blazor working for you?" />
Index.razor頁面在項目編譯後會生成Index.razor.g.cs文件,其位置如圖所示,在obj文件夾下面:
具體的源碼如下:
1: [Microsoft.AspNetCore.Components.LayoutAttribute(typeof(MyLayout))]
2: [Microsoft.AspNetCore.Components.RouteAttribute("/")]
3: public partial class Index : Microsoft.AspNetCore.Components.ComponentBase
4: {
5: #pragma warning disable 1998
6: protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
7: {
8: __builder.AddMarkupContent(0, "<h1>Hello, world!</h1>\r\n\r\nWelcome to your new app.\r\n\r\n");
9: __builder.OpenComponent<BlazorApp.Client.Shared.SurveyPrompt>(1);
10: __builder.AddAttribute(2, "Title", "How is Blazor working for you?");
11: __builder.CloseComponent();
12: }
13: #pragma warning restore 1998
14: }
可以看到,以上代碼並不難理解,同時它還有兩個特性,一個是布局的標識,一個是路由的標識。緊接着就是該類重寫了BuildRenderTree方法,這個以後會說。需要提醒的是,大家在寫Blazor項目遇到問題時,可以多查看razor頁面所生成的C#代碼。
創建簡單組件
需要注意的是,在Blazor項目中,包括razor頁面,布局以及組件都隱式或顯示的繼承自ComponentBase的。
在Blazor.Client項目的Shared文件夾中,我們創建一個Components文件夾用於存放我們自定義的組件。
(1)創建頁面,並暫且先使用下面的默認內容
(2)然後在_Imports.razor文件中添加@using BlazorApp.Client.Shared.Components,以使得該組件可以全局使用,從這個引用的命名空間來看,我們新建的組件的命名空間默認就是文件所在的位置
(3)在Index.razor頁面使用
(4)運行後的結果如圖所示
單項綁定
如果讀者接觸了比較多的前端框架,可能會對理解單項綁定有很大的幫助,這實際上一種插值或者說是動態數據的佔位(變量)。
大部分情況下,我們都希望我們的組件是可以輸出動態內容,那麼我們應該如何實現呢?這個時候我們就需要在頁面上寫一寫C#代碼了。
(1)在MyComponent組件中添加參數,並標記[Parameter]特性
(2)在Index頁面上,添加按鈕和事件功能,可以參考Counter頁面的按鈕
這個頁面的功能我們暫時只關注如何傳值即可,也就是在調用MyComponent組件的時候,調用其屬性Counter並賦值。
(3)運行效果如下所示
組件事件
添加組件自定義事件,其實就是聲明一個EventCallback<int>類型的組件參數,如下代碼所示:
1: [Parameter]
2: public EventCallback<int> EventSample { get; set; }
(1)自定義組件修改
增加一個計數方法,可以參考Counter中代碼。在IncrementCount方法中,採用await ClickCountCallback.InvokeAsync(currentCount*2)方式傳值給Index.Razor頁面,頁面源碼:
1: @*<h3>My Component</h3>*@
2:
3: 這裡是自定義組件的區域,我點擊了幾次 <strong style="color: red">@currentCount</strong>
4: <br>
5: <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
6:
7: @code {
8: private int currentCount { get; set; }
9:
10: [Parameter]
11: public EventCallback<int> ClickCountCallback { get; set; }
12:
13: private async Task IncrementCount()
14: {
15: currentCount++;
16: await ClickCountCallback.InvokeAsync(currentCount*2);
17: }
18: }
(2)Index.razor頁面
1: @page "/"
2: @layout MyLayout
3: <h1> </h1>
4:
5: @*Welcome to your new app.*@
6:
7: @*<SurveyPrompt Title="How is Blazor working for you?" />*@
8:
9: <h2>Index頁面的CurrentCount=<strong style="color: red">@currentCount</strong></h2>
10:
11: <br>
12: <MyComponent ClickCountCallback="IncrementCount1" />
13: <br />
14:
15: @code {
16: private int currentCount;
17:
18: private void IncrementCount1(int value)
19: {
20: currentCount = value;
21: }
22: }
使用currentCount接收自定義組件中傳來的值。
運行效果如下:
Index.razor頁面生成的C#源碼如下所示:
會往RenderTreeBuilder對象中添加AddAttribute,用於接收自定義組件回調過來的值。