Blazor帶我重玩前端(六)

本文主要討論Blazor事件內容,因爲blazor事件部分不少,因此會分紅上下兩篇,本文爲第二篇。web

雙向綁定

概述

如圖所示微信

  • 當點擊單項綁定的時候,MyOnewayComponent裏的屬性值會發生變化,這種變化是單項的,僅僅只是本地副本的值的變化,並不會引起父頁面的值發生變化。但當點擊父頁面的Click Me的時候,會修改MyOnewayComponent的屬性值會被修改。因此單項綁定強調的是佔位,以達到動態輸出的目的。
  • 當點擊雙向綁定的時候,三個值會同步發生變化。即使點擊父頁面的Click Me,也不會覆蓋掉MyTwoWayComponent的屬性值,這說明父頁面和MyTwoWayComponent頁面的值發生了雙向綁定,會致使數據同步變化。
  • 雙向綁定,綁定的是Blazor組件和dom元素,就像是宏指令同樣。也就是說,當該組件首次運行時,輸入框的值來自於CurrentValue屬性,當用戶輸入新的值後,CurrentValue也將會被設置成新的值。

示例

雙向綁定有一個重要特徵就是使用@bind-進行數據綁定,以前我建立了兩個組件,咱們來看一下這兩個組件的源代碼:MyOnewayComponent:dom

<div> MyComponent CounterValue is @CounterValue</div><button @onclick=UpdateCounterValue>Update</button>@code {
[Parameter] public int CounterValue { get; set; }
void UpdateCounterValue() { CounterValue++; }}

MyTwoWayComponent:async

<div> MyComponent CounterValue is @CounterValue</div><button @onclick=UpdateCounterValue>Update</button>@code {
[Parameter] public int CounterValue { get; set; }
[Parameter] public EventCallback<int> CounterValueChanged { get; set; }
async Task UpdateCounterValue() { CounterValue++; await CounterValueChanged.InvokeAsync(CounterValue); }}

以上代碼能夠看到有明顯的不一樣,MyTwoWayComponent包含一個EventCallback 類型的屬性,其命名是CounterValueChanged,看起來像是屬性值後綴Changed,其調用方法也變成了async Task,該方法代表,當CounterValue發生變化的時候,會經過CounterValueChanged來通知事件源頁面該值發生了變化。額外嘗試一下,若是咱們直接使用MyOnewayComponent 來演示雙向綁定,會發生什麼,咱們使用以下代碼運行一下看看: 編輯器

<MyOnewayComponent @bind-CounterValue="@currentCount" />

運行後,發現報錯了,錯誤信息是:Unhandled exception rendering component: Object of type 'BlazorApp.Client.Pages.MyOnewayComponent' does not have a property matching the name 'CounterValueChanged'。因而可知,咱們的命名規則是強制的,其必須是所綁定EventCallBack 的屬性名後綴Changed。 ide

BuildTree源碼

#pragma warning disable 1998protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder){ __builder.AddContent(8, "Click me"); __builder.CloseElement(); __builder.AddMarkupContent(9, "\r\n<br>\r\n<br>\r\n\r\n"); __builder.OpenComponent<BlazorApp.Client.Pages.MyOnewayComponent>(10); __builder.AddAttribute(11, "CounterValue", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<System.Int32>(#nullable restore currentCount
#line default#line hidden#nullable disable )); __builder.AddAttribute(12, "CounterValueChanged", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.CreateInferredEventCallback(this, __value => currentCount = __value, currentCount)); __builder.CloseComponent();}
  • 8-15行是單項綁定的內容
  • 16-18行是雙向綁定的內容

級聯值和參數

概述

級聯值和參數是一種將值從組件傳遞到其全部子組件的方法,在Blazor中,採用CascadingValue來實現,子組件經過聲明同一類型的屬性(用[CascadingParameter]屬性修飾)來收集並賦值。當級聯值發生更新的時候,這種更新將傳遞到全部的子組件,同時這組件將會自動調用StateHasChanged 。通常狀況下,咱們的CascadingValue中可能會須要傳遞多個值的變化,那麼這種變化是如何進行的呢。是經過兩種方式,一種是類型推導,一種是命名傳值。性能

類型推導

我建立了兩個組件,分別是FirstComponent,SecondComponent。FirstComponent源碼以下:flex

<CascadingValue Value="@CascadingIndex"> <CascadingValue Value="@CascadingName"> <SecondComponent></SecondComponent> </CascadingValue></CascadingValue>@code {int CascadingIndex = 10000;
string CascadingName = "FirstComponent";}

SecondComponent源碼以下:ui

<h3>SecondComponent</h3><p> CascadingValue Is <strong>@SecondValue</strong></p>@code { [CascadingParameter] int SecondValue { get; set; }}

傳值的過程當中,咱們只有一個int類型的屬性,因此該值會顯示10000,以下圖所示:若是咱們修改一下FirstComponent的源碼,將其中的string類型的屬性刪除掉,同時增長一個新的int類型的屬性,以下源碼所示:運行結果以下:因而可知,當子組件遇到多個相同類型的屬性的時候,會選擇離子組件最近的屬性的值並傳遞到本身的屬性中去。this

命名傳值

命名賦值就很單純了,主要考慮綁定正確的名稱就行。修改後FirstComponent的源碼以下,須要指定Name

 <CascadingValue Value="@CascadingIndex" Name="CascadingIndex"> <CascadingValue Value="@Total" Name="Total"> <SecondComponent></SecondComponent> </CascadingValue></CascadingValue>
@code { int CascadingIndex{ get; set; } = 10000;
int Total{ get; set; } = 2;}

SecondComponent源碼以下,能夠指定名稱已接收值的傳遞

<h3>SecondComponent</h3><p> CascadingValue Is <strong>@SecondValue</strong></p>@code { [CascadingParameter(Name = "CascadingIndex")] int SecondValue { get; set; }}

運行後的結果以下,值又變回了10000,有朋友可能會想,我不想設置SecondComponent中CascadingParameter的Name值,可是我能夠設置成FirstComponent中某個已經綁定的Name的名稱。以下所示:FirstComponent源碼不變,SecondComponent源碼以下:

<h3>SecondComponent</h3><p> CascadingValue Is <strong>@Total</strong></p>@code { [CascadingParameter] int Total { get; set; }}

運行結果以下所示:因而可知,不設置子組件中CascadingParameter的Name值,是沒法接收傳遞的值的。

性能問題

默認狀況下,Blazor會持續監控級聯值的變化,並將其傳遞到全部子組件中,這將會佔用必定的資源,並可能致使性能問題。若是咱們能夠肯定,咱們的級聯值不會發生變化,能夠設置CascadingValue中參數IsFixed的值爲true,這樣的Blazor就不會監控級聯值的變化了。

<CascadingValue Value="@CascadingIndex" IsFixed="true"> <SecondComponent></SecondComponent></CascadingValue>


本文分享自微信公衆號 - DotNet技術平臺(DotNetCore_Moments)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索