前面學習了Blazor的特色、環境搭建及基礎知識,如今咱們嘗試的作個實際的組件。css
Ant Design是螞蟻金服是基於Ant Design設計體系的 UI 組件庫,主要用於研發企業級中後臺產品。目前官方是基於React和Angular實現的,今年也推出了Vue的實現。其組件涵蓋面較廣,其組件風格及交互效果仍是比較驚豔的,後面準備利用Ant Design的樣式文件利用Blazor模仿幾個組件的實現。html
因爲也是新學的Blazor開發,可能實現的方式有些笨拙,但願高手提出寶貴意見,先看看實現的Button 按鈕、Grid 柵格、導航欄的效果。node
先來看看Button按鈕,它支持多種風格,是否只顯示圖標,loading狀態等。實現步驟及主要代碼且聽我娓娓道來,git
首先去antd.css cdn 下載穩定版的css文件,放到 wwwroot 文件夾下。再 _Host.cshtml 引用該文件。github
AButtonBase類定義了按鈕的屬性參數;註冊了class名稱(例如:class="ant-btn ant-btn-primary")的計算表達式,class內容是根據屬性參數的設置狀況計算出來的。瀏覽器
屬性set 的 ClassMapper.Dirty() 是通知樣式名生成方法屬性改變了須要從新生成樣式名稱。服務器
而ClassMapper是用於註冊組件須要用到的樣式構建類,PrefixCls()是添加樣式共用的前綴,Add有多個重載,能夠是直接的樣式名稱;也能夠是根據第一個參數的bool表達式來肯定,第二個參數的樣式是否啓用。antd
using BlazorAntDesign.Core; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.RenderTree; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace BlazorAntDesign.General { public class AButtonBase : BaseComponent { #region Properties /// <summary> /// 設置按鈕大小,可選值爲 Small、Large 或者不設 /// </summary> [Parameter] protected AButtonSizes ButtonSize { get => buttonSize; set { buttonSize = value; ClassMapper.Dirty(); } } private AButtonSizes buttonSize = AButtonSizes.Default; /// <summary> /// 設置按鈕類型,可選值爲 Primary、Dashed、Danger 或者不設 /// </summary> [Parameter] protected AButtonTypes ButtonType { get => buttonType; set { buttonType = value; ClassMapper.Dirty(); } } private AButtonTypes buttonType = AButtonTypes.Default; /// <summary> /// 設置按鈕形狀,可選值爲 Circle、 Round 或者不設 /// </summary> [Parameter] protected AButtonShapes ButtonShape { get => buttonShape; set { buttonShape = value; ClassMapper.Dirty(); } } private AButtonShapes buttonShape = AButtonShapes.Default; /// <summary> /// 設置 button 原生的 type 值,可選值請參考 HTML 標準 /// </summary> [Parameter] protected AButtonHTMLTypes HtmlType { get; set; } = AButtonHTMLTypes.Button; /// <summary> /// 按鈕標題 /// </summary> [Parameter] protected string Title { get => title; set { title = value; ClassMapper.Dirty(); } } private string title; /// <summary> /// 設置按鈕的圖標名稱 /// </summary> [Parameter] protected string IconName { get; set; } /// <summary> /// 將按鈕寬度調整爲其父寬度的選項 /// </summary> [Parameter] protected bool Block { get => block; set { block = value; ClassMapper.Dirty(); } } private bool block; /// <summary> /// 幽靈屬性,使按鈕背景透明。幽靈按鈕將按鈕的內容反色,背景變爲透明,經常使用在有色背景上。 /// </summary> [Parameter] protected bool Ghost { get => ghost; set { ghost = value; ClassMapper.Dirty(); } } private bool ghost; /// <summary> /// 設置按鈕載入狀態 /// </summary> [Parameter] protected bool Loading { get => loading; set { loading = value; ClassMapper.Dirty(); } } private bool loading; /// <summary> /// 按鈕失效狀態 /// </summary> [Parameter] protected bool Disabled { get; set; } [Parameter] protected RenderFragment ChildContent { get; set; } /// <summary> /// 點擊按鈕時的回調 /// </summary> [Parameter] public EventCallback<UIMouseEventArgs> OnClick { get; set; } //protected System.Action Clicked { get; set; } protected bool click_animating { get; set; } #endregion protected override void RegisterClasses() { ClassMapper.PrefixCls("ant-btn") .Add(() => ClassMapper.GetEnumName(buttonSize)) .Add(() => ClassMapper.GetEnumName(buttonType)) .Add(() => ClassMapper.GetEnumName(buttonShape)) .Add(() => Block, () => "block") .Add(() => Ghost, () => "background-ghost") .Add(() => Loading, () => "loading") .Add(() => string.IsNullOrEmpty(title) && ChildContent == null, () => "icon-only"); base.RegisterClasses(); } protected void buttonDown() { click_animating = false; } protected void buttonUp() { click_animating = true; } } }
AButtonSizes、AButtonTypes、AButtonShapes、AButtonHTMLTypes 屬性參數是定義的枚舉,例如:app
namespace BlazorAntDesign.General { /// <summary> /// 按鈕尺寸選項 /// </summary> public enum AButtonSizes { /// <summary> /// 缺省,中 /// </summary> [ClassNamePart("")] Default, /// <summary> /// 大 /// </summary> [ClassNamePart("lg")] Large, /// <summary> /// 小 /// </summary> [ClassNamePart("sm")] Small } }
namespace BlazorAntDesign.General { /// <summary> /// 按鈕類型選項 /// </summary> public enum AButtonTypes { /// <summary> /// 缺省,次按鈕 /// </summary> [ClassNamePart("")] Default, /// <summary> /// 主按鈕 /// </summary> Primary, /// <summary> /// /// </summary> Ghost, /// <summary> /// 虛線按鈕 /// </summary> Dashed,
Danger } }
AButtonBase類繼承自自定義的BaseComponent,BaseComponent繼承自Blazor的ComponentBase類。ide
BaseComponent主要定義了全部組件共用的屬性,ElementId、Style、ClassMapper等,
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; namespace BlazorAntDesign.Core { public abstract class BaseComponent : ComponentBase, IDisposable { #region Members private bool disposed; private ElementRef elementRef; #endregion #region Constructors public BaseComponent() { ElementId = Utils.IDGenerator.Instance.Generate; ClassMapper = new ClassMapper(); RegisterClasses(); } #endregion #region Methods protected virtual void RegisterClasses() { ClassMapper.AddCustomClass(() => customClass); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { if (ClassMapper != null) { //ClassMapper.Dispose(); ClassMapper = null; } } disposed = true; } } #endregion #region Properties /// <summary> /// 定義用戶自定義的 ClassName /// </summary> [Parameter] protected string ClassName { get => customClass; set { customClass = value; ClassMapper.Dirty(); } } private string customClass; /// <summary> /// Gets the reference to the rendered element. /// </summary> public ElementRef ElementRef { get => elementRef; protected set => elementRef = value; } /// <summary> /// 獲取 element 惟一 Id. /// </summary> public string ElementId { get; } [Parameter] protected string Style { get; set; } /// <summary> /// 獲取 ClassMapper. /// </summary> protected ClassMapper ClassMapper { get; private set; } #endregion } }
@inherits BlazorAntDesign.General.AButtonBase <button class="@ClassMapper.Class" type="@(Enum.GetName(typeof(AButtonHTMLTypes), HtmlType).ToLower())" ant-click-animating-without-extra-node="@(click_animating ? "true" : "")" disabled="@Disabled" @onkeydown="@buttonDown" @onmousedown="@buttonDown" @onkeyup="@buttonUp" @onmouseup="@buttonUp" @onclick="@OnClick"> @*圖標*@ @if (Loading) {<AIcon IconName="loading"></AIcon>} else { if (!string.IsNullOrEmpty(IconName)) {<AIcon IconName="@IconName"></AIcon>} } @*標題*@ @if (!string.IsNullOrEmpty(Title)) {<span>@Title</span>} @*子內容*@ @ChildContent</button>
其中 @inherits BlazorAntDesign.General.AButtonBase 是代碼隱藏方式,指定後臺代碼繼承自AButtonBase類,button class="@ClassMapper.Class",將採用的樣式根據指定的屬性值計算出來賦值給button的class屬性。下面根據屬性設置判斷是否顯示圖標、標題、子內容。
創建DemoButton.razor文件,樣例代碼以下:
@page "/DemoButton" @using BlazorAntDesign.General; <div style="border:1px solid beige;padding:10px"> <AButton Title="Default"></AButton> <AButton Title="Primary" ButtonType="AButtonTypes.Primary"></AButton> <AButton Title="Danger" ButtonType="AButtonTypes.Danger"></AButton> <AButton Title="Dashed" ButtonType="AButtonTypes.Dashed"></AButton> <AButton Title="Disabled" Disabled="true"></AButton> <AButton ButtonType="AButtonTypes.Primary" IconName="download" ButtonShape="AButtonShapes.Circle"></AButton> <AButton Title="下載" ButtonType="AButtonTypes.Primary" IconName="download" ButtonShape="AButtonShapes.Round"></AButton> <AButton Title="下載" ButtonType="AButtonTypes.Primary" IconName="download"></AButton> <AButtonGroup><AButton ButtonType="AButtonTypes.Primary" IconName="left">Backward</AButton><AButton ButtonType="AButtonTypes.Primary">Forward<AIcon IconName="right" /></AButton></AButtonGroup> <AButton Title="Loading" ButtonType="AButtonTypes.Primary" Loading="true"></AButton> <AButton Title="Click me!" ButtonType="AButtonTypes.Primary" Loading="@isLoading" OnClick="@(()=> { isLoading = true; })"></AButton> </div> <div style="border:1px solid beige;padding:10px;margin-top:5px"> <AButton IconName="search" ButtonType="AButtonTypes.Primary" ButtonShape="AButtonShapes.Circle"></AButton> <AButton IconName="search" ButtonType="AButtonTypes.Primary">按鈕</AButton> <AButton IconName="search" ButtonShape="AButtonShapes.Circle"></AButton> <AButton IconName="search">按鈕</AButton> <AButton IconName="search" ButtonType="AButtonTypes.Dashed" ButtonShape="AButtonShapes.Circle"></AButton> <AButton IconName="search" ButtonType="AButtonTypes.Primary">按鈕</AButton> </div> @code{ private bool isLoading = false; private void LoadingClick() { isLoading = true; } }
@page "/DemoButton" 爲組件路由
@using BlazorAntDesign.General; 爲應用組件命名空間
好了Button的實現思路今天就學習到這了,但願有興趣的同仁共同窗習探討,讓Blazor真正走向SPA開發的舞臺,讓.net core七龍珠面向全棧開發,更好的擁抱社區,刷新業界對.net體系的認知。
Blazor 在發展:
微軟已將 Blazor 移出了實驗階段,進入了官方預覽版。使用組件模型進行服務器端渲染的 Blazor 版本將與.NET Core 3 的最終版本一塊兒發佈(請參閱.NET Core 路線圖),客戶端版本將在隨後不久發佈。還有工做要完成:調試體驗極其有限,必須改進;有機會經過提早編譯生成本機 Wasm 來優化代碼性能;在將未使用的代碼庫發送到瀏覽器以前,須要從庫中刪除未使用的代碼,從而下降整體大小(這個過程稱爲樹抖動)。對 WebAsssembly 的興趣和採用與日俱增,藉助 Blazor,編寫能夠在任何地方運行的 C#和.NET 代碼的夢想終於實現了。
原文出處:https://www.cnblogs.com/liuxtj/p/11377680.html