日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

ASP.NET Core Blazor Webassembly 之 组件

發(fā)布時間:2023/12/4 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core Blazor Webassembly 之 组件 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

關(guān)于組件

現(xiàn)在前端幾大輪子全面組件化。組件讓我們可以對常用的功能進行封裝,以便復(fù)用。組件這東西對于搞.NET的同學(xué)其實并不陌生,以前ASP.NET WebForm的用戶控件其實也是一種組件。它封裝html代碼,封裝業(yè)務(wù)邏輯,對外提供屬性事件等信息,它完完全全就是個組件,只是用戶控件跑在服務(wù)端,而現(xiàn)在的組件大多數(shù)直接跑在前端。現(xiàn)在Blazor Webassembly微軟正式把組件帶到前端,讓我們看看它是怎么玩的。

第一個組件

廢話不多說下面開始構(gòu)建第一個組件。這個組件很簡單就是綠色的面板加一個標(biāo)題的容器,我們就叫它GreenPanel吧。

新建Blazor Webassembly項目

前幾天的build大會,Blazor Webassembly已經(jīng)正式release了。我們更新最新版的Core SDK就會安裝正式版的模板。

新建項目選Blazor Webassembly App項目模板

新建GreenPanel組件

在pages命令下新建一個文件夾叫做components,在文件夾下新建一個razor組件,命名為GreenPanel.razor。

注意:組件的命名必須大寫字母開頭

添加代碼如下:

<div class="green-panel"><div class="title">Green panel</div><div class="content"></div> </div> <style>.green-panel{background-color: green;height:400px;width:400px;}.green-panel .title {border-bottom:1px solid #333;height:30px;}.green-panel .content {} </style> @code { override void OnInitialized(){base.OnInitialized();} }

一個組件主要是由html,style ,code等組成。html,style用來控制ui表現(xiàn)層,code用來封裝邏輯。

注意:Blazor目前沒有樣式隔離技術(shù),所以寫在組件內(nèi)的style有可能會影響其他html元素

使用組件

使用組件跟其他框架大體是相同的,直接在需要使用的地方使用以我們組件名作為一個html元素插入:
如果不在同一層目錄下,則需要導(dǎo)入命名空間。在_Imports.razor文件內(nèi)引用組件的命名空間:

... @using BlazorWasmComponent.Components

在index頁面使用組件:

<GreenPanel></GreenPanel>

運行一下:

組件類

每個組件最后都會編譯成一個C#類,讓我們用ILSPy看看一眼長啥樣:

// BlazorWasmComponent.Components.GreenPanel using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; public class GreenPanel : ComponentBase {protected override void BuildRenderTree(RenderTreeBuilder __builder){__builder.AddMarkupContent(0, "<div class=\"green-panel\">\r\n <div class=\"title\">\r\n Green panel\r\n </div>\r\n <div class=\"content\">\r\n </div>\r\n</div>\r\n\r\n");__builder.AddMarkupContent(1, "<style>\r\n .green-panel{\r\n background-color: green;\r\n height:400px;\r\n width:400px;\r\n }\r\n .green-panel .title {\r\n border-bottom:1px solid #333;\r\n height:30px;\r\n }\r\n .green-panel .content {\r\n }\r\n</style>");}protected override void OnInitialized(){base.OnInitialized();} }

GreenPanel組件會編譯成一個GreenPanel類,繼承自ComponentBase基類。里面有幾個方法:

  • BuildRenderTree 用來構(gòu)建html,css等ui元素

  • 其它code部分會也會被合并到這個類里面

  • 生命周期

    了解組件聲明周期對我們使用組件有很大的幫助。一個組件的生命周期主要依次以下幾個階段:

  • OnInitialized、OnInitializedAsync

  • OnParametersSet、OnParametersSetAsync

  • OnAfterRender、OnAfterRenderAsync

  • Dispose

  • 如果要在每個生命階段插入特定的邏輯,請重寫這些方法:

    @implements IDisposable @code {protected override void OnInitialized(){Console.WriteLine("OnInitialized");base.OnInitialized();}protected override Task OnInitializedAsync(){Console.WriteLine("OnInitializedAsync");return base.OnInitializedAsync();}protected override void OnParametersSet(){Console.WriteLine("OnParametersSet");base.OnParametersSet();}protected override Task OnParametersSetAsync(){Console.WriteLine("OnParametersSetAsync");return base.OnParametersSetAsync();}protected override void OnAfterRender(bool firstRender){Console.WriteLine("OnAfterRender");base.OnAfterRender(firstRender);}protected override Task OnAfterRenderAsync(bool firstRender){Console.WriteLine("OnAfterRenderAsync");return base.OnAfterRenderAsync(firstRender);}public void Dispose(){Console.WriteLine("Dispose");} }

    注意:組件默認(rèn)并不繼承IDisposable接口,如果要重寫Dispose方法請手工使用@implements方法繼承接口IDisposable

    運行一下,并且切換一下頁面,使組件銷毀,可以看到所有生命周期方法依次執(zhí)行:

    組件屬性

    我們定義組件總是免不了跟外部進行交互,比如從父組件接受參數(shù),或者把自身的數(shù)據(jù)對外暴露。我們可以使用[Parameter]來定義一個組件的屬性。這里叫做Parameter,估計是為了跟C#里的屬性(property,attribute)進行區(qū)分。
    對我們的GreenPanel組件進行改進,支持從外部定義標(biāo)題的內(nèi)容:

    <div class="green-panel"><div class="title">@Title</div><div class="content"></div> </div> <style>.green-panel {background-color: green;height: 400px;width: 400px;}.green-panel .title {border-bottom: 1px solid #333;height: 30px;}.green-panel .content {} </style> @code {[Parameter]public string Title { get; set; }protected override void OnInitialized(){base.OnInitialized();} }

    在父組件使用:

    @page "/" <GreenPanel Title="Panel A"></GreenPanel>

    運行一下:

    上面?zhèn)鬟f的是簡單類型String,下面讓我們試試傳遞復(fù)雜類型的數(shù)據(jù)進去。我們繼續(xù)對GreenPanel改造。改造成ColorPanel,它接受一個Setting對象來設(shè)置標(biāo)題跟背景顏色。

    定義Setting類:

    public class PanelSetting{public string Title { get; set; }public string BgColor { get; set; }}

    定義ColorPanel:

    <div class="green-panel"><div class="title">@Setting.Title</div><div class="content"></div> </div> <style>.green-panel {background-color: @Setting.BgColor;height: 400px;width: 400px;}.green-panel .title {border-bottom: 1px solid #333;height: 30px;}.green-panel .content {} </style> @using BlazorWasmComponent.models; @code {[Parameter]public PanelSetting Setting { get; set; }protected override void OnInitialized(){base.OnInitialized();} }

    在父組件使用:

    @page "/" <p>@PanelSetting.Title</p> <p>@PanelSetting.BgColor</p> <ColorPanel Setting="PanelSetting"></ColorPanel> @using BlazorWasmComponent.models; @code{ public PanelSetting PanelSetting { get; set; }protected override void OnInitialized(){PanelSetting = new PanelSetting{BgColor = "Red",Title = "Panel RED"};base.OnInitialized();} }

    運行一下:

    注意一篇WebAssembly初探里有個錯誤,當(dāng)時認(rèn)為這個屬性是單向數(shù)據(jù)流,經(jīng)過試驗子組件對父組件傳入的數(shù)據(jù)源進行修改的時候其實是會反應(yīng)到父組件的,只是如果你使用@符號綁定數(shù)據(jù)的時候并不會像angularjs,vue等立馬進行刷新。關(guān)于這個事情感覺可以單獨寫一篇,這里就不細(xì)說了。

    組件事件

    我們的組件當(dāng)然也可以提供事件,以供外部訂閱,然后從內(nèi)部激發(fā)來通知外部完成業(yè)務(wù)邏輯,實現(xiàn)類似觀察者模式。繼續(xù)改造ColorPanel,當(dāng)點擊時候?qū)ν鈷伋鍪录?br />使用EventCallback、EventCallback< T > 來定義事件:

    <div class="green-panel" @onclick="DoClick"><div class="title">@Setting.Title</div><div class="content"></div> </div> <style>.green-panel {background-color: @Setting.BgColor;height: 400px;width: 400px;}.green-panel .title {border-bottom: 1px solid #333;height: 30px;}.green-panel .content {} </style> @using BlazorWasmComponent.models; @code {[Parameter]public PanelSetting Setting { get; set; }[Parameter]public EventCallback OnClick { get; set; }protected override void OnInitialized(){base.OnInitialized();}public void DoClick(){OnClick.InvokeAsync(null);} }

    父組件訂閱事件:

    @page "/" <p>子組件點擊次數(shù):@ClickCount </p> <ColorPanel Setting="PanelSetting" OnClick="HandleClick"></ColorPanel> @using BlazorWasmComponent.models; @code{ public PanelSetting PanelSetting { get; set; }public int ClickCount { get; set; }protected override void OnInitialized(){PanelSetting = new PanelSetting{BgColor = "Red",Title = "Panel RED"};base.OnInitialized();}private void HandleClick(){ClickCount++;} }

    運行一下,并點擊子組件,父組件的計數(shù)器會被+1:

    子內(nèi)容

    當(dāng)我們定義容器級別的組件時往往需要往組件內(nèi)傳遞子內(nèi)容。比如我們的ColorPanel明顯就有這種需求,這個Panel內(nèi)部會被放上其它元素或者其它組件,這個時候我們可以使用ChildContent屬性來實現(xiàn)。

    <div class="green-panel" @onclick="DoClick"><div class="title">@Setting.Title</div><div class="content">@ChildContent</div> </div> <style>.green-panel {background-color: @Setting.BgColor;height: 400px;width: 400px;}.green-panel .title {border-bottom: 1px solid #333;height: 30px;}.green-panel .content {} </style> @using BlazorWasmComponent.models; @code {[Parameter]public PanelSetting Setting { get; set; }[Parameter]public EventCallback OnClick { get; set; }[Parameter]public RenderFragment ChildContent { get; set; }protected override void OnInitialized(){base.OnInitialized();}public void DoClick(){OnClick.InvokeAsync(null);} }

    定義一個類型為RenderFragment名稱為ChildContent的屬性,然后在html內(nèi)使用@ChildContent來指代它。這樣子內(nèi)容就會被替換到指定的位置。
    父組件使用,我們給ColorPanel的內(nèi)部設(shè)置一個文本框吧:

    @page "/" <p>子組件點擊次數(shù):@ClickCount </p> <ColorPanel Setting="PanelSetting" OnClick="HandleClick">輸入框: <input /> </ColorPanel> @using BlazorWasmComponent.models; @code{ public PanelSetting PanelSetting { get; set; }public int ClickCount { get; set; }protected override void OnInitialized(){PanelSetting = new PanelSetting{BgColor = "Red",Title = "Panel RED"};base.OnInitialized();}private void HandleClick(){ClickCount++;} }

    運行一下看看我們的文本框會不會出現(xiàn)在panel內(nèi)部:

    @ref

    因為我們的組件使用是在html內(nèi),當(dāng)你在@code內(nèi)想要直接通過代碼操作子組件的時候可以給子組件設(shè)置@ref屬性來直接獲取到子組件的對象。繼續(xù)改造ColorPanel,在它初始化的時候生產(chǎn)一個ID。

    <div class="green-panel" @onclick="DoClick"><div class="title">@Setting.Title</div><div class="content">@ChildContent</div> </div> <style>.green-panel {background-color: @Setting.BgColor;height: 400px;width: 400px;}.green-panel .title {border-bottom: 1px solid #333;height: 30px;}.green-panel .content {} </style> @using BlazorWasmComponent.models; @code {public string ID { get; set; }[Parameter]public PanelSetting Setting { get; set; }[Parameter]public EventCallback OnClick { get; set; }[Parameter]public RenderFragment ChildContent { get; set; }protected override void OnInitialized(){ID = Guid.NewGuid().ToString();base.OnInitialized();}public void DoClick(){OnClick.InvokeAsync(null);} }

    修改父組件,添加一個按鈕,當(dāng)點擊的時候直接獲取子組件的Id:

    @page "/" <p>子組件ID:@subId </p> <ColorPanel Setting="PanelSetting" OnClick="HandleClick" @ref="colorPanel">輸入框: <input /> </ColorPanel> <button @onclick="GetSubComponentId" class="btn btn-info">獲取子組件ID</button> @using BlazorWasmComponent.models; @code{ private string subId;private ColorPanel colorPanel;public PanelSetting PanelSetting { get; set; }public int ClickCount { get; set; }protected override void OnInitialized(){PanelSetting = new PanelSetting{BgColor = "Red",Title = "Panel RED"};base.OnInitialized();}private void HandleClick(){ClickCount++;}private void GetSubComponentId (){this.subId = colorPanel.ID;} }

    運行一下:

    @key

    當(dāng)使用循環(huán)渲染組件的時候請在組件上使用@key來加速Blazor的diff算法。有了key就可以快速的區(qū)分哪些組件是可以復(fù)用的,哪些是要新增或刪除的,特別是在對循環(huán)列表插入對象或者刪除對象的時候特別有用。如果使用過vue就應(yīng)該很容易明白有了key可以降低虛擬dom算法的復(fù)雜度,在這里猜測blazor內(nèi)部應(yīng)該也是類似的算法。

    @page "/" @foreach (var key in List) {<ColorPanel @key="key" Setting="PanelSetting"></ColorPanel> } @using BlazorWasmComponent.models; @code{ public List<String> List = new List<string>{Guid.NewGuid().ToString(),Guid.NewGuid().ToString(),Guid.NewGuid().ToString()};public PanelSetting PanelSetting { get; set; }protected override void OnInitialized(){PanelSetting = new PanelSetting{BgColor = "Red",Title = "Panel RED"};base.OnInitialized();} }

    太晚了就這樣吧,喜歡的話請點個贊,謝謝!

    相關(guān)內(nèi)容:
    ASP.NET Core Blazor 初探之 Blazor WebAssembly

    ASP.NET Core Blazor 初探之 Blazor Server

    關(guān)注我的公眾號一起玩轉(zhuǎn)技術(shù)

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

    總結(jié)

    以上是生活随笔為你收集整理的ASP.NET Core Blazor Webassembly 之 组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。