通过Blazor使用C#开发SPA单页面应用程序(4) - Ant Design

通过Blazor使用C#开发SPA单页面应用程序(1)

通过Blazor使用C#开发SPA单页面应用程序(2)

通过Blazor使用C#开发SPA单页面应用程序(3)


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

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

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

640?wx_fmt=gif

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

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

640?wx_fmt=jpeg

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

 640?wx_fmt=png

原文链接:https://www.cnblogs.com/liuxtj/p/11377680.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

640?wx_fmt=jpeg


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

POJ 1741 Tree(点分治)

POJ 1741 Tree 思路 男人八题中的一题&#xff0c;写完这题算是18\frac{1}{8}81​个男人了&#xff01; 这题是树上距离的计数问题&#xff0c;能够通过巧妙地排序加双指针来解决&#xff0c; 统计距离应该大家都会地&#xff0c;我就来说明一下如何计数吧。 假设我们已经求…

P1975 [国家集训队]排队(三维偏序)

P1975 [国家集训队]排队 查询逆序对数目&#xff0c;交换两个数的位置 首先逆序对是一个经典的二维偏序问题&#xff0c;然后现在问题变为静态&#xff0c;我们可以使用三维偏序来处理多出来的限制。或者也可以使用带修主席树处理。

Mercurial黄昏,Bitbucket宣布全面转向Git

源代码托管平台 Bitbucket 宣布将逐步放弃对版本控制系统 Mercurial 的支持。Bitbucket 推出于 2008 年&#xff0c;当时集中式版本控制是比较普遍的&#xff0c;Mercurial 是其中的典型代表&#xff0c;但是当前 Git 才是主流&#xff0c;它已经成为了大部分开源项目的首选版本…

HDU 4812 D Tree (点分治) (2013ACM/ICPC亚洲区南京站现场赛)

HDU 4812 D Tree 思路 点对距离相等并且要求输出字典序最小的点对&#xff0c;距离相等不就是点分治裸题了嘛&#xff0c; 照着这个思路出发我们只要记录下所有点对是满足要求的&#xff0c;然后再去找字典序最小的点对就行了&#xff0c; 接下来就是考虑如何求最小点对了&…

P2754 [CTSC1999]家园 / 星际转移问题(网络流)

P2754 [CTSC1999]家园 / 星际转移问题 经典问题&#xff0c;利用分层图来跑网络流。

使用 Azure DevTest Lab 搭建云端开发测试环境

点击上方蓝字关注“汪宇杰博客”导语程序员和测试工程师经常需要自己搭环境用于开发和测试目的&#xff0c;这些机器可能只会使用很短一段时间。通常我们会在本机使用 Hyper-V、VMWare 之类的虚拟机产品&#xff0c;或者使用企业IT管理员分配的虚拟机去完成这项工作。然而安装配…

dotNET Core WebAPI 统一处理(返回值、参数验证、异常)

现在 Web 开发比较流行前后端分离现在 Web 开发比较流行前后端分离&#xff0c;我们的产品也是一样&#xff0c;前端使用Vue&#xff0c;后端使用 dotNet Core WebAPI &#xff0c;在写 API 的过程中有很多地方需要统一处理文档参数验证返回值异常处理本文就说说 API 的统一处理…

HDU 4059 The Boss on Mars (容斥)(2011 Asia Dalian Regional Contest)

The Boss on Mars 思路 显然我们可以求得∑i1ni46n515n410n3−n30\sum_{i 1} ^{n} i ^ 4 \frac{6n^5 15n^4 10n ^3 - n}{30}∑i1n​i4306n515n410n3−n​&#xff0c;接下来就是考虑把其中不与nnn互质的数给踢出去了&#xff0c;显然我们可以考虑容斥。 假设np1a1p2a2p3…

P2764 最小路径覆盖问题(网络流)

P2764 最小路径覆盖问题 最小链覆盖问题&#xff0c;关键在于怎么转化为网络流问题&#xff0c;我们可以发现网络流的常见套路就是将一个点拆成出点和入点来处理&#xff0c;对于一条链恰好满足出点和入点匹配的性质&#xff0c;所以可以拆点然后对应连边&#xff0c;这样跑最…

.net测试篇之单元测试/集成测试神器Autofixture

autofixture简介有了单元测试框架加上Moq(后面我们会用单独章节来介绍moq),可以说测试问题基上都能搞定了.然而有了AutoFixture对单元测试来说可以说是如虎添翼,AutoFixture并且它能与moq,rhinomock等框架结合,对单元测试带来的便捷性,可维护性和扩展性更是难以言表,只有用用了…

杜教筛入门详解

杜教筛入门 前置知识 迪利克雷卷积&#xff08;*&#xff09;&#xff1a; 先介绍三个重要的函数&#xff1a; 元函数ϵ(n)[n1]\epsilon(n) [n 1]ϵ(n)[n1] 原函数可以看成是迪利克雷卷积里的单位元&#xff0c;即(ϵ∗f)(n)f(n)(\epsilon * f)(n) f(n)(ϵ∗f)(n)f(n)&am…

P2765 魔术球问题(网络流)

P2765 魔术球问题 给出n根柱子&#xff0c;求解可以将最多多少编号的球放在上面&#xff0c;并且满足相邻的编号和为完全平方数。 n<50 这个数据范围我们可以选择网络流&#xff0c;然后将对应点连边&#xff0c;然后每次枚举编号&#xff0c;将其加入残量网络&#xff0c…

DotNetCore 3.0 助力 WPF本地化

概览随着我们的应用程序越来越受欢迎&#xff0c;我们的下一步将要开发多语言功能。方便越来越多的国家使用我们中国的应用程序&#xff0c;基于 WPF 本地化&#xff0c;我们很多时候使用的是系统资源文件&#xff0c;可是动态切换本地化&#xff0c;就比较麻烦了。实现思路现在…

#6229. 这是一道简单的数学题(反演 + 杜教筛)

#6229. 这是一道简单的数学题 推式子 ∑i1n∑j1ilcm(i,j)gcd(i,j)(∑i1n∑j1nlcm(i,j)gcd(i,j)n)∗inv2所以重点求∑i1n∑j1nlcm(i,j)gcd(i,j)∑i1n∑j1nijgcd(i,j)2∑d1n∑i1nd∑j1ndij(gcd(i,j)1)∑d1n∑k1ndμ(k)k2(∑i1nkdi)2我们另tkd&#xff0c;得到∑t1n(∑i1nti)2∑k…

P2766 最长不下降子序列问题(网络流)

P2766 最长不下降子序列问题 求解LIS长度k求解长度为k的不下降子序列个数&#xff0c;并且一个数只能使用一次求解长度为k的不下降子序列个数&#xff0c;第一个数和第n个数可以使用任意次 首先利用dp可以求解出以每个点开始的最长不下降子序列&#xff0c;然后可以类似于最短…

开源题材征集 + MVCEF Core 完整教程小结

到目前为止&#xff0c;我们的MVCEF Core 完整教程的理论部分就全部结束了&#xff0c;共20篇&#xff0c;覆盖了核心的主要知识点。下一阶段是实战部分&#xff0c;我们将会把这些知识点串联起来&#xff0c;用10篇(天)来完成一个开源项目。现向园友征集题材&#xff0c;你提需…

P2770 航空路线问题(网络流)

P2770 航空路线问题 似乎是一个经典的双调路径问题&#xff0c;然后这里使用网络流解决了&#xff0c;本质上要求两条路径没有经过同一个点&#xff0c;并且总长度最大&#xff0c;所以我们实际上可以跑网络流&#xff0c;然后拆点限制路径没有交点。

欧拉心算(反演 + 积性函数筛)

欧拉心算 推式子 ∑i1n∑j1nϕ(gcd(i,j))∑d1nϕ(d)∑i1nd∑j1nd[gcd(i,j)1]∑d1nϕ(d)∑k1ndμ(k)(⌊nkd⌋)2另tkd∑t1n(⌊nt⌋)2∑d∣tϕ(d)μ(td)另f(n)∑d∣nϕ(d)μ(nd)我们考虑如何得到这个函数的前缀和&#xff0c;显然这是一个积性函数有如下性质f(1)1f(p)ϕ(1)μ(p)ϕ…

对微软的敌视何时休? 从一篇语言评论文章对C#的评价说起

看到一篇公众号文章《2020年什么编程语言最受欢迎&#xff0c;待遇最高&#xff1f;》&#xff0c;其中对C#的描述如下&#xff1a;点击阅读原文&#xff0c;看到这是一篇翻译文章&#xff1a;https://codinginfinite.com/top-programming-languages-2020-stats-surveys/这篇文…