zoukankan      html  css  js  c++  java
  • 通过Blazor使用C#开发SPA单页面应用程序(4)

      前面学习了Blazor的特点、环境搭建及基础知识,现在我们尝试的做个实际的组件。

      Ant Design是蚂蚁金服是基于Ant Design设计体系的 UI 组件库,主要用于研发企业级中后台产品。目前官方是基于React和Angular实现的,今年也推出了Vue的实现。其组件涵盖面较广,其组件风格及交互效果还是比较惊艳的,后面准备利用Ant Design的样式文件利用Blazor模仿几个组件的实现。

      由于也是新学的Blazor开发,可能实现的方式有些笨拙,希望高手提出宝贵意见,先看看实现的Button 按钮、Grid 栅格、导航栏的效果。

     先来看看Button按钮,它支持多种风格,是否只显示图标,loading状态等。实现步骤及主要代码且听我娓娓道来,

     1、引用样式文件

      首先去antd.css cdn 下载稳定版的css文件,放到 wwwroot 文件夹下。再 _Host.cshtml 引用该文件。

    2、建立 AButtonBase 类

      AButtonBase类定义了按钮的属性参数;注册了class名称(例如:class="ant-btn ant-btn-primary")的计算表达式,class内容是根据属性参数的设置情况计算出来的。

      属性set 的 ClassMapper.Dirty() 是通知样式名生成方法属性改变了需要重新生成样式名称。

      而ClassMapper是用于注册组件需要用到的样式构建类,PrefixCls()是添加样式共用的前缀,Add有多个重载,可以是直接的样式名称;也可以是根据第一个参数的bool表达式来确定,第二个参数的样式是否启用。

    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 属性参数是定义的枚举,例如:

    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类。

      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
        }
    }

    3、建立 AButton.razor

    @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属性。下面根据属性设置判断是否显示图标、标题、子内容。

    4、使用 AButton

     建立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 代码的梦想终于实现了。

      .net core将踏上新的征程:

     

  • 相关阅读:
    真的是简单、简洁、简易、简明之道!!!
    HashMap源码解读
    Jenkins Pipeline
    C语言二级指针free|一级指针存储内存地址
    openjdk编译和调试,JVM编译调试
    java linux和win jdk安装包jdk1.6、jdk1.7和jdk1.8 7u80 8u181 8u161
    关于java代码打包成jar在控制台运行变慢的问题
    Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen
    mongodb副本集
    condition
  • 原文地址:https://www.cnblogs.com/liuxtj/p/11377680.html
Copyright © 2011-2022 走看看