.NET开发者的机遇与Web Blazor基础(有彩蛋)

 一.唠唠WebAssembly的发展历程

  目前有不少支持WebAssembly的项目,但发展最快的是Blazor,这是一个构建单页面的.NET技术,目前已经从Preview版本升级到了beta版本,微软计划在2020年5月发布Blazor的第一个版本。html

  Blazor是什么?它是一项将C#和.NET都放入浏览器的Microsoft技术。它使用WebAssembly来工做,WebAssembly是一种高性能的管道,能够将代码预编译为紧凑的二进制格式。最重要的是,每一个主流浏览器(包括移动版本)都支持WebAssembly。前端

  十年前,JavaScript统治世界还不是很明显。Flash和Silverlight也正在运行。这二个都须要使用浏览器插件来完成工做,而且都以不一样的用户界面方法替换了HTML。这种方法使他们在功能方面遥遥领先于JavaScript,但随着移动互联网的出现,他们就慢慢过期。python

  但随后从最初的Javascript再到微软的JScript和CEnvi的ScriptEase三足鼎立,再到最后的统一标准,当时微软凭借Windows系统捆绑Internet Explorer的先天优点击溃Netscape后,两大巨头就此进入了长达数年的静默期,JavaScript就是在这样的状况下被构想出来的,当时的浏览器之王,Netscape Navigator创始人Marc Andreessen认为Netscape须要一种“glue language”来支持HTML,让Web设计师和兼职程序员能够很容易地使用它来组装诸如图像和插件之类的组件,且代码是能够直接写在网页标记中。除此以外微软的步步紧逼也迫使Andreessen不得不聘请Brendan Eich,及早将Scheme编程语言嵌入到Netscape Navigator中。1995年,JavaScript以Mocha为名开发,并于9月在Netscape Navigator 2.0的测试版中首次发布,当时被称为LiveScript,12月,在Netscape Navigator 2.0 beta 3中部署时被重命名为JavaScript 。虽然Netscape Navigator在Chrome、Internet Explorer和Firefox等多款浏览器的围追堵截中最终落败,可是JavaScript却推进了网页的发展,并一直被沿用至今。git

  这是一个讽刺。在JavaScript征服世界的同时,播下了一颗很小的种子,这可能会在未来的某个时候暗示JavaScript的终结。那颗种子是名为asm.js的实验技术。程序员

  这是Mozilla的开发人员在2013年完成的一个古怪的实验。他们正在寻找在浏览器中运行高性能代码的方法。可是与插件不一样,asm.js并何尝试在浏览器旁边运行。相反,它的目的是直接经过Javascript的虚拟化。编程

  从本质上讲,asm.js是简洁,优化的JavaScript语法。它比普通的JavaScript运行得更快,由于它避免了该语言的慢动态部分。可是认识到它的网络浏览器也能够应用其余优化,从而大大提升性能。换句话说,asm.js遵循黄金法则- 不要破坏网络 -同时提供通往将来改进的途径。Firefox团队使用asm.js以及名为Emscripten的转码工具来获取用C ++构建的实时3D游戏,并将其放入Web浏览器中,而且仅在JavaScript和原始野心上运行。api

  有人问为何asm.js好在哪里,简单而言,它的性能比JavaScript高几百倍,固然是在没有谷歌的V8引擎之下,由于JavaScript是若类型语言,它须要猜想你的数据类型来进行编译,这样的状况下,在我看来它确定须要遍历完一个方法,而后再进行运算,与其这样我为何不打个标识呢?固然在不破坏JavaScript的状况下,arm.js选择了一个骚气的想法,若是你想你的数据类型是int,那么声明一个值就变成了变量名|0,就这样它的目的就达到了。浏览器

  尽管asm.js实验产生了一些使人眼花撩乱的演示,但工做的开发人员基本上忽略了它。对他们来讲,这只是超越现代的一个有趣方面。但这随着WebAssembly的建立而改变。服务器

  WebAssembly既是asm.js的后继产品,又是一项大相径庭的技术。这是一种紧凑的二进制代码格式。像asm.js同样,WebAssembly代码也被输入到JavaScript执行环境中。它具备相同的沙箱和相同的运行时环境。与asm.js同样,WebAssembly的编译方式也能够提升效率。可是如今,这些效率比有之前更加明显,而且浏览器能够彻底跳过JavaScript解析阶段。对于普通的逻辑,WebAssembly远比常规JavaScript快,几乎与本机编译的代码同样快。网络

   WebAssembly于2015年首次出现。现在,桌面和移动设备上的四大浏览器(Chrome,Edge,Safari和Firefox)已彻底支持它。尽管能够经过将WebAssembly代码转换为asm.js来实现向后兼容,但Internet Explorer不支持它。就让IE凉透吧!但须要注意的是WebAssembly没法回避JavaScript,由于它已锁定在JavaScript运行时环境中。实际上,WebAssembly须要与至少一些普通的JavaScript代码一块儿运行,由于它不能直接访问页面。这意味着若是不经过JavaScript层,就没法操纵DOM或接收事件。

   听我提及来,这是一个限制,但聪明的微软开发者已经找到了走私的方法,在浏览器中下载一个微型.NET运行时,做为已编译的WASM文件。此运行时处理JavaScript互操做,并提供基本服务,它能给咱们提供GC或者其它用法。Blazor不是惟一一个由WebAssembly支持的实验。考虑一下Pyodide,它旨在将Python放入浏览器中,并带有用于数据分析的高级数学工具包。据我所知这应该使用emscripten的编译器。

   人们常说,什么时候Javascript可以替代服务器端语言,又有人说何时能够代替桌面级应用程序,因此WebAssembly并非用来代替JavaScript的。而是为了解决现代问题,若是它作到了,那就真的作到了!因此做为一个程序员,你应该对WebAssembly引发足够的重视,将来快速加载Web应用程序的需求确定会增长。

   就如今咱们的.NET Core提供了两种Blazor模板,包括Blazor Server 以及 Blazor WebAssembly。

  • Blazor Server使用熟悉的.NET环境在Web服务器上运行代码。诀窍是浏览器和服务器之间的通讯方式。当用户与页面进行交互时,JavaScript代码将回调到发生实际页面生命周期的服务器。(要创建此链接,该页面使用名为SignalR的Microsoft API )运行服务器端代码后,Blazor Server呈现该页面并将更改发送回Web页面,该Web页面将相应地进行更新。
  • Blazor WebAssembly使用由WebAssembly提供支持的微型.NET运行时在浏览器中运行代码。您的客户端代码能够访问许多熟悉的.NET库,而且您使用C#语言编写它,您仍然能够像在JavaScript页面中同样在Web服务器上调用API。

  Blazor Server是一种具备一些有趣用例的技术,可是因为不断的通讯,您显然会牺牲一些性能-甚至不用问脱机功能。Blazor WebAssembly是受到最多宣传的一种,也是咱们在本文中探讨的一种。

  关于Blazor,程序员最多见的误解是将其C#代码编译为WebAssembly,而后发送到浏览器,而后执行。这种方法并不是不可能-Blazor的建立者暗示他们未来可能会尝试这种技术。可是现在Blazor的工做方式并非如此。

  换句话说,现在的Blazor是当您访问使用Blazor的网页时,该页面将从下载按比例缩小的.NET运行时开始。而后它将下载您的应用程序以及您的应用程序使用的任何其余.NET库,全部这些都在其本机IL中。最后,Blazor运行时执行IL。

二.配置您的开发环境

   因为Blazor是一个预发布的早期Beta产品。基础结构的关键部分正在发生变化,您将没法得到与其余类型的Microsoft项目相同级别的工具支持。我尝试在Visual Studio 2019中进行编码,须要注意的是您须要勾选.NET FrameWork 4.8 以及 .NET Core 3.0 + ,这样您才具备Web Assembly的项目。完成设置后,您能够轻松建立Blazor项目。只需启动Visual Studio,建立一个新项目,而后选择“ Blazor App”项目便可。Visual Studio会询问您是否须要Blazor Server应用程序或Blazor WebAssembly应用程序.

 三.Blazor的数据绑定与组件传值

  因为关于Blazor的.NET Core 又一杀器! Web Blazor框架横空出世!一篇我编写的文章,未能说起更深刻的内容,那么如今我将要介绍一下高级的Blazor用法,到最后还会有一个糖果,园友力做的Blazor UI!多么激动人心的时刻,那么赶快开始吧.

3.1Child Component

  在Blazor的Child Component中可使用[Parameter] 关键字,来进行传值的定义,咱们能够这么来作,如今只是提一下这个概念,下面会仔细说下组件之间如何进行跨组件绑定值。

<div>
    <p>标题:@title</p>
</div>
@code{
    [Parameter]
    public string title { get; set; }
}

随后在调用时,Visual Studio IDE 就能够直接向您的视觉进行提示输入相关属性。

<Demorazor title="Hello 博客园的兄弟们!"></Demorazor>

运行效果以下:

3.2 single Bind and Two-way binding

single bind就不用说了,新建项目自带的模板Counter示例那就是如此。

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

此处 @currentCount 值根据点击按钮的数量递增Click me。<p>标记元素中的值会自动刷新,无需任何组件刷新。

two-way binding 咱们能够自定义咱们的事件 一共分为二中绑定方式 包括@bind 和 @Bind-Value,值得一提的是还能够经过使用event参数指定@bind-value属性, 使用其余事件来绑定属性或字段。例如第四个文本框就是绑定changeString采用oninput事件的属性,以到达在文本框的值更改时激发,通过个人测试若是你的绑定事件是Javascript中不存在的,那么也无妨,不会报出系统级别的异常,我想若是是从IL转换到WebAssembly中,就会直接过滤掉,可是Visual Studio 2019 没有给咱们提示,也让咱们编译经过,即便是当前的最高16.0.4 预览版也是如此,这个是令我诧异的。

<p>
    <span>在这里可使用bind-value 或者 bind 固然这里确保您不使用其它事件!</span>
    <input @bind-value="changeString" />
    <p>这是我输入的内容: @changeString</p>
</p>
<p>
    <span>oninput</span>
    <input @bind-value="changeString" @bind-value:event="oninput" />
</p>

@code {
    string changeString = "";
}  

运行效果以下:

 3.3 Component bindings

   想要跨组件进行绑定属性值,可使用,@bind-{property}可在其中跨组件绑定属性值,咱们试着尝试,首先咱们建立一个子控件,这个blazor就叫Baby,有一个身份证Id的属性和出生地址。

   EventCallback的用法很是普遍,它能够跨组件共享方法和属性,如不写下面的两个属性,则就会报错。

@page "/baby"
<h2>Child Compoent</h2>
<p>出生的Baby IdentityCard:@Baby_IdentityCrad_Id</p>
<h3>在{@Baby_new_Address} 生的</h3>
@code {
    [Parameter]
    public string Baby_IdentityCrad_Id{ get; set; }

    /// <summary>
    /// 这个属性也是牛的雅皮~~~ hhh
    /// </summary>
    [Parameter]
    public string Baby_new_Address{ get; set; }
    
    [Parameter]
    public EventCallback<string> Baby_IdentityCrad_IdChanged { get; set; }

    [Parameter]
    public EventCallback<string> Baby_new_AddressChanged { get; set; }
}

   有什么样的儿子就会有什么样的爸爸? 如今咱们建立出父亲,那就直接叫作一个Father.razor吧~

@page "/father"
<h3>Father</h3>

<Baby @bind-Baby_IdentityCrad_Id="@id_Card"
      @bind-Baby_new_Address="@address">
</Baby>
<button class="btn btn-primary" @onclick="@ChangeTheYear">new baby()</button>
@code {
    public string id_Card { get; set; }
    public string address { get; set; }
    private void ChangeTheYear()
    {
        id_Card = Guid.NewGuid().ToString();
        address = "老张";
    }
}

运行效果以下:

 

 若是要在子组件中定义事件,则能够MouseEventArgs来接受设备上的事件,而后再进行附加事件。

[Parameter]
public EventCallback<MouseEventArgs> OnClick { get; set; }

四.级联传值

   在某些状况下, 使用组件参数将数据从祖先组件流式传输到附属组件是不方便的, 尤为是在有多个组件层时。 级联值和参数经过提供一种方便的方法, 使上级组件为其全部子代组件提供值。 级联值和参数还提供了一种方法来协调组件。咱们试着去构建一个例子,首先建立一个最顶层的组件。

@page "/myDome"
<p><span>姓名:</span><input @bind="@pName" /></p>
<p><span>年龄:</span><input @bind-value="@pAge" @bind-value:event="oninput"/></p>
<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;width:200px;">
    <p>Parent Component</p>
    <div style="padding:10px;">
        <p> 年龄 :@Age</p>
        <ChildComponent />
    </div>
</div>
@code{
    [CascadingParameter(Name = "ProfileAge")]
    int Age { get; set; }
}

ChildComponent.razor:

<div style="background-color:beige;width:200px;">
    <p>Child Component</p>
    <p>名称 : @Name.ToString()</p>
</div>

@code{
    [CascadingParameter(Name = "ProfileName")]
    string Name { get; set; }
}

 运行效果以下:

 

 能够发现,一级直接将二级和三级的组件进行了数据穿透,不过须要注意的是CascadingValue的Name必定要和CascadingParameter的Name相同,不然将会执行错误。

五.路由

   从古至今,任何大型的开发框架,都是具备路由的,不然可能将会没法工做,其实Blazor的启动页也就使用了路由,这是毋庸置疑的。当你的组件带有 @page 指令时,将为生成的类指定 RouteAttribute 指定路由模板的。 在运行时,路由器将使用 RouteAttribute 查找组件类,并呈现哪一个组件包含与请求的 URL 匹配的路由模板。

@page "/luyou"
@page "/luyou/{text}"

<h1>Blazor is @Text!</h1>

@code {
    [Parameter]
    public string Text { get; set; }

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}

运行效果以下:

在上面的示例中应用了两个 @page 指令。 第一个容许导航到没有参数的组件。 第二个 @page 指令采用 {text} 路由参数,并将该值分配给 Text 属性。

关于Blazor的基础入门我们这篇就说到这里,相信你必定以为Blazor了不得!它是一个现代的开源框架。它也由一家拥有悠久历史的公司拥有,该公司放弃了昨天的闪亮新技术。所以,大多数开发人员都应该谨慎对待Blazor。只要JavaScript可以执行Blazor能够作的全部事情,而没有下载大小,性能和新工具堆栈带来的额外挑战,大多数开发人员将一如既往。

这并不意味着Blazor不能在全部这些领域都占有一席之地。它甚至可能成为.NET Web应用程序开发中的主导力量。可是若是我今天必须下注,这就是我要依靠的东西。WebAssembly是将来。但就目前而言,Blazor只是一种有趣的可能性。

六.彩蛋

就如今!个人好朋友宇辰正在开发一款名为Blazui的UI组件。它为何叫Blazui?

Blazor + Element UI = Blazui,Element UI 的blazor版本,无JS,无TS,用 .Net 写前端的 UI 框架,非 Silverlight,非 WebForm,开箱即用!!

Blazui 演示地址:http://blazui.com:9000。QQ群:74522853,码云地址:https://gitee.com/wzxinchen/blazui

参考Blazor使用的前提条件:

  1. 安装 .Net Core 3.0
  2. 安装 VS2019
  3. 安装全部 VS2019 Blazor Extension

如今Blazor正在逐渐变好,让咱们即刻出发!.NET Core 不仅是开源!

相关文章
相关标签/搜索