? 今天我們來看看Blazor開發(fā)的一些基本知識。
一、Blazor組件結(jié)構(gòu)
?Blazor中組件的基本結(jié)構(gòu)可以分為3個部分,如下所示:
//Counter.razor
//Directives section 指令部分 @page "/counter" //Razor HTML section Razor HTML部分
<h1>Counter</h1> <p>Current count: @currentCount</p> <buttonclass="btn
btn-primary" onclick="@IncrementCount">Click me</button> //code sections 功能部分
@code {private int currentCount = 0; private void IncrementCount() {
currentCount++; } }
? 指令部分:
* 路由 ? - @page
* DI ? ? - @inject
* 導(dǎo)入庫 - @using
?
? Razor HTML 部分:
? ? ? ? Razor HTML語法是C#代碼與HTML的結(jié)合。此部分最終在瀏覽器中呈現(xiàn)。
? 指令部分:
? ? ?? 組件中的函數(shù)部分包含用戶操作函數(shù)(事件方法),局部變量和從/向父/子組件傳遞的屬性。
? 當(dāng)然如果愿意,這部分也可以單獨寫道類文件中。
?
二、Blazor的屬性和參數(shù)
?? 我們看看屬性和參數(shù),
<button id="btnClickMe" class="btn btn-primary" onclick="@IncrementCount"
>Click me</button>
? 在這里,在按鈕元素的id,class和onclick被稱為HTML屬性。
? 類似地,組件的定義方式與HTML元素相同,
?//MyDemo.razor
@page "/myDome" <h3>MyDemo</h3> <ChildComponent Title="來自MyDemo"
></ChildComponent>
? 在Child Component中,該屬性Title與裝飾的子組件函數(shù)部分中的屬性匹配 [Parameter] 關(guān)鍵字。
//ChildComponent.razor
//Child Component <div> <p>標(biāo)題 : @Title</p> </div> @code { [Parameter] private
string Title { get; set; } }
?運行效果如下:
?
三、Blazor的數(shù)據(jù)綁定
?
? Blazor的數(shù)據(jù)綁定同時提供了單向綁定和雙向綁定兩種機制。
? (一)單向綁定:
? 單向綁定在Blazor中簡單直接,無需任何UI刷新。還記得Counter示例嗎,他顯示了單向數(shù)據(jù)綁定,
@page "/counter" <h1>Counter</h1> <p>Current count: @currentCount</p> <button
class="btn btn-primary" @onclick="@IncrementCount">Click me</button> @code { int
currentCount =0; void IncrementCount() { currentCount++; } }
? 此處 @currentCount 值根據(jù)點擊按鈕的數(shù)量遞增Click me。<p>標(biāo)記元素中的值會自動刷新,無需任何組件刷新。
?? (二)雙向綁定:
?在Blazor中可以實現(xiàn)雙向綁定,與一些流行的JS語言框架相比,Blazor為雙向綁定提供了多種實現(xiàn)方式,Blazor可以優(yōu)雅地進行編寫。
?
(1) @bind屬性在Blazor中提供雙向數(shù)據(jù)綁定。下面的示例復(fù)選框演示在同一組件中的bind屬性,
@page "/myDome" <span>請選擇:</span> <input type="checkbox" @bind="myChecked" />
<p>我選擇了 :@myChecked.ToString()</p> @code { bool myChecked { get; set; } = true;
}
?? 運行效果如下,是不是很簡單,很優(yōu)雅。
?? 再來一個控制樣式表的例子看看,
@page "/myDome" <p> <span>顯示/隱藏:</span> <input type="checkbox" @bind="myChecked
" /> </p> <p style="display:@(myChecked ? "inline":"none")">看到我了</p> @code {
bool myChecked { get; set; } = true; }
?(2)
@bind屬性在Blazor中提供雙向數(shù)據(jù)綁定,但是只提供了默認(rèn)的綁定事件,如果們想在不同的時機觸發(fā)雙向綁定該怎么辦呢,別急同樣很簡單的,我們看看下面的代碼,展示了幾種綁定實例,
@page "/myDome" <p> <span>onchange 方式一</span> <input @bind="changeString" />
</p> <p> <span>onchange 方式二</span> <input type="text" value="@changeString"
@onchange="@((UIChangeEventArgs _e) => changeString = _e.Value.ToString())" />
</p> <p> <span>onchange 方式三</span> <input@bind-value="changeString" @bind-value:
event="onchange" /> </p> <p> <span>oninput</span> <input @bind-value="
changeString" @bind-value:event="oninput" /> </p> <p>這是我輸入的內(nèi)容: @changeString</p>
@code {string changeString = ""; }
? 運行效果如下,
?
? ? 呈現(xiàn)組件時, input元素value的值來自changeString。 當(dāng)用戶在文本框中鍵入內(nèi)容并離開時,
將觸發(fā)事件onchange更改changeString的值。原則上, @bind將表達式的當(dāng)前值value與changeString相關(guān)聯(lián),
并使用注冊的處理程序來處理更改。
? ? 除了使用@bind語法處理onchange事件之外, 還可以通過使用event參數(shù) (@bind-value:event)
指定@bind-value屬性,
使用其他事件來綁定屬性或字段。例如第四個文本框就是綁定changeString采用oninput事件的屬性,以到達在文本框的值更改時激發(fā)。
?? (三)組件之間綁定: ?
?(1)綁定可識別組件參數(shù), @bind-{property}可在其中跨組件綁定屬性值。
?
//MyDemo.razor @page "/myDome" <h1>Parent Component</h1> <p>當(dāng)前時間:
@ParentNow</p> <hr /> <ChildComponent @bind-Now="ParentNow" /> <hr /> <button
class="btn btn-primary" @onclick="@ChangeTheYear"> 更新當(dāng)前時間 </button> @code {
[Parameter]public DateTime ParentNow { get; set; } = DateTime.Now; private void
ChangeTheYear() { ParentNow= DateTime.Now; } }
?
//ChildComponent.razor <h2>Child Component</h2> <p>當(dāng)前時間: @Now</p> @code {
[Parameter]public DateTime Now { get; set; } [Parameter] public
EventCallback<DateTime> NowChanged {get; set; } }
?? 以上代碼中,子組件 (ChildComponent) 具有一個Now組件參數(shù)和NowChanged回調(diào)參數(shù),父組件MyDemo使用
ChildComponent并將ParentNow參數(shù)從父級綁定到子組件上Now的參數(shù)上,如果通過點擊MyDemo中的"更新當(dāng)前時間"按鈕來更改屬性的值,
Now則將更新ChildComponent屬性,將新值呈現(xiàn)在 UI中。其中,參數(shù)Now是可綁定的,
因為它具有NowChanged與參數(shù)類型匹配的伴隨事件。按照約定,其等效于
<ChildComponent @bind-Now="ParentNow" @bind-Now:event="NowChanged" />
? 運行效果:
?
?(2)組件之間傳遞的數(shù)據(jù)通過組件屬性及其屬性映射發(fā)生,此方法使用委托Action<T>類型。
//MyDemo.razor @page "/myDome" <h3>Parent Component</h3> <p>來自Child組件:
@childString</p> <p> <input @bind="inputText" /> </p> <hr /> <ChildComponent
ToChild="@inputText" FromChild="@ReceivedFromChild"> </ChildComponent> @code{
private string inputText = ""; private string childString = ""; private void
ReceivedFromChild(string str) { childString = str; StateHasChanged(); } } //
ChildComponent.razor <h4>Child Component</h4> <p> <input @bind="inputText" />
<button @onclick="@PassToParent">顯示到Parent組件</button> </p> <p>來自Parent組件 :
@ToChild</p> @code{ [Parameter] private string ToChild { get; set; }
[Parameter] Action<string> FromChild { get; set; } private string inputText = ""
;private void PassToParent() { FromChild(inputText); } }
?? 這里FromChild是ChildComponent中的屬性,屬性使用Action<string>數(shù)據(jù)類型將值從Child傳遞給Parent
Component。在Parent中,有相應(yīng)的接收器函數(shù)ReceivedFromChild和字符串參數(shù),這將在ChildComponent中按鈕單擊并觸發(fā)通知時觸發(fā)PassToParent,但是為了通知狀態(tài)已在父組件中更改,我們使用StateHasChanged()的內(nèi)置Blazor函數(shù)通知組件其狀態(tài)已更改。
? 運行效果如下:
?
四、 生命周期方法
?(1)
OnInitializedAsync和OnInitialized方法,執(zhí)行代碼來初始化組件。要執(zhí)行異步操作,請在操作上使用OnInitializedAsync和await關(guān)鍵字。
(2)OnParametersSetAsync和OnParametersSet當(dāng)組件已接收到的參數(shù)從其父和值被分配給屬性被調(diào)用。這些方法在組件初始化后以及每次呈現(xiàn)組件時執(zhí)行。
(3)OnAfterRenderAsync并OnAfterRender在組件完成渲染后調(diào)用。此時填充元素和組件引用。使用此階段使用呈現(xiàn)的內(nèi)容執(zhí)行其他初始化步驟,例如激活對呈現(xiàn)的DOM元素進行操作的第三方JavaScript庫。
?
五、級聯(lián)值和參數(shù)
?
? 在某些情況下, 使用組件參數(shù)將數(shù)據(jù)從祖先組件流式傳輸?shù)礁綄俳M件是不方便的, 尤其是在有多個組件層時。 級聯(lián)值和參數(shù)通過提供一種方便的方法,
使上級組件為其所有子代組件提供值。 級聯(lián)值和參數(shù)還提供了一種方法來協(xié)調(diào)組件。
?
Blazor提供了一種在整個RenderTree(所有組件)中傳遞數(shù)據(jù)的方法,使用CascadingValue和CascadingParameter不需要傳遞作為組件屬性,并且可以通過裝飾屬性[CascadingParameter]而不用在RenderTree(子組件)中接收值[Parameter]。
//MyDemo.razor @page "/myDome" <p><span>姓名:</span><input @bind="@pName"
/></p> <p><span>年齡:</span><input @bind="@pAge" /></p> <hr /> <CascadingValue
Value="@pName" Name="ProfileName"> <CascadingValue Value="@pAge" Name="
ProfileAge"> <ParentComponent /> </CascadingValue> </CascadingValue> @code {
private string pName { get; set; } = "張三"; private int pAge { get; set; } = 35;
} //ParentComponent.razor <div style="background-color:darkgray"> <p>Parent
Component</p> <div style="padding:10px;"> <ChildComponent /> </div> </div> //
ChildComponent.razor <div style="background-color:beige"> <p>Child
Component</p> <p>輸入的 姓名: @Name , 年齡 : @Age.ToString()</p> </div> @code{
[CascadingParameter(Name= "ProfileName")] string Name { get; set; }
[CascadingParameter(Name= "ProfileAge")] int Age { get; set; } }
? 代碼中MyDemo的姓名、年齡穿透ParentComponent直接級聯(lián)到ChildComponent中。
?
在這里CascadingParameter,Name參數(shù)必須與Name帶有CascadingValue組件的屬性匹配,如果我們沒有提到任何Name,則CascadingParameter中的變量類型與CascadingValue中的Value屬性匹配。
? 運行效果:
?
六、路由
?
? 我們在看一個SPA中一個基本但很重要的功能路由??蛻舳寺酚煽梢酝ㄟ^使用@page指令裝飾組件來在Blazor中完成。
@page "/myDome" @page "/myDome/{text}"
? @page在上面的示例中應(yīng)用了兩個指令。
? 第一個允許在沒有參數(shù)的情況下導(dǎo)航到組件。
? 第二個@page指令采用{text}route參數(shù)并將值賦給Text屬性。
?
好了今天Blazor的組件開發(fā)就先學(xué)習(xí)到這,有意猶未盡的可以查看官方文檔
<https://docs.microsoft.com/zh-cn/aspnet/core/blazor/components?view=aspnetcore-3.0>
深入學(xué)習(xí)。
?
熱門工具 換一換
感谢您访问我们的网站,您可能还对以下资源感兴趣:
调教肉文小说-国产成本人片免费av-空姐av种子无码-在线观看免费午夜视频-综合久久精品激情-国产成人丝袜视频在线观看软件-大芭区三区四区无码-啊啊好爽啊啊插啊用力啊啊-wanch视频网-国产精品成人a免费观看