前言

我相信你已经掌握了Blazor的基本知识和概念,大致知道了它的一个工作原理。再次强调一下,Blazor 是一门 “基于C#语言的前端技术”

前端框架主要的核心理念是以数据为驱动的方式,而传统的JQuery是用的DOM驱动。所以 Blazor 作为前端框架,自然也是以数据驱动的方式。

单向绑定

顾名思义就是输出,将变量的值输出到页面上。

很简单的一段演示:

bladex架构图 bladex框架优缺点 blazor框架_Blazor

@{
    int a = 1;
    int b = 10;
    int c = a + b;
}
 
设 a=@a, b=@b, 那么 a+b 的值 c 是多少?
<br />
答:a+b=@c

其中,@{ ...代码块... } 表示可以编写任意的 C# 代码。而使用 @变量 的方式可以将变量进行输出,或者你也可以使用 @(变量) 的方式,

学过 mvc 的同学对这个肯定不陌生了。

双向绑定

通过数据驱动的方式将输入控件的内容同步到变量中。

直接看以下的一个效果:

bladex架构图 bladex框架优缺点 blazor框架_控件_02


当文本框失去焦点时,在下方输出刚才输入的内容。

在传统的 JQ 时代,我们的代码大概是这样的:

$('#textbox').on('blur', function(){
	var textValue = $(this).val();
	$('#text').text(textValue);
})

好久没有写 JQ 代码了,依稀还记得好像是这样写的。

而我们 Blazor 的代码则是这样:

<EditForm Model="model">
    <InputText @bind-Value="model.Name"/>
    <p>
        @model.Name
    </p>
</EditForm>
 
@code{
    UserViewModel model = new UserViewModel();
 
    class UserViewModel
    {
        public string Name { get; set; }
    }
}

首先 @code { ... }@{ ... } 都是用来声明,大括号内是编写 C# 代码的代码块。不同的是 @{ } 可以编写任意代码,但不能进行有层级关系的代码块,比如声明一个类。

@code{ } 则是用于编写更高级的定义关系的代码块,好比 cs 文件如下的内容:

namespace XXXX
{
	class YYY
	{
	     // 代码块
	}
}

回到刚才那张动图中,我们的代码大致如下:

<EditForm Model="model">
    <InputText @bind-Value="model.Name" />
    <p>
        @model.Name
    </p>
</EditForm>
@code{
    UserViewModel model = new UserViewModel();

    class UserViewModel
    {
        public string Name { get; set; }
    }
}

InputText 是一个组件,使用 @bind-Value 对某一个字段进行双向绑定,意思是当文本框有变化时,会自动触发 @OnValueChanged 事件。

注意事项

  • InputText 要求要放到组件 EditForm 组件中,否则会出现以下错误:

InvalidOperationException: Microsoft.AspNetCore.Components.Forms.InputText requires a cascading parameter of type EditContext. For example, you can use Microsoft.AspNetCore.Components.Forms.InputText inside an EditForm.

随便找一个翻译软件翻译过来则是:

Microsoft.AspNetCore.Components.Forms.InputText 需要 EditContext 类型的级联参数。例如,您可以使用Microsoft.AspNetCore.Components.Forms.InputText 在 EditForm 中。

  • 光声明了 EditForm 还不行,否则会出现以下错误:

EditForm requires a Model parameter, or an EditContext parameter, but not both.

翻译如下:

EditForm 需要一个 Model 参数,或者一个 EditContext 参数,但不能同时需要这两个参数。

  • 按照上面的指定了 Model 参数后,但文本框没进行绑定操作,还会出现以下错误:

Microsoft.AspNetCore.Components.Forms.InputText requires a value for the ‘ValueExpression’ parameter. Normally this is provided automatically when using ‘bind-Value’.

翻译如下:

Microsoft.AspNetCore.Components.Forms.InputText需要“ValueExpression”参数的值。通常在使用“bind-Value”时自动提供。

意思就是,你需要使用 bind-Value 属性对需要的字段进行双向绑定。

普通 HTML 控件的双向绑定

我有时候只想使用普通的 HTML 控件,并且也想使用双向绑定功能,那怎么办呢?

先看一下这个片段:

bladex架构图 bladex框架优缺点 blazor框架_AspNetCore_03

这里有一个文本框,我们实现了输入即输出的双向绑定操作,而代码如下:

<input type="text" @bind="@Input" @bind:event="oninput"/>
<br />
@Input
@code{
    string Input { get; set; }
}

这是一个普通的文本框控件,而使用 @bind 指令来表示需要进行双向绑定的变量,之后有一个 @bind:event 表示的是双向绑定的触发事件。这里的事件必须是当前这个 html 控件所支持的事件。

疑问:如果不写 @bind:event 会怎样呢?

<input type="text" @bind="@Input" />
<br />
@Input

@code{
    string Input { get; set; }
}

bladex架构图 bladex框架优缺点 blazor框架_Blazor_04

会默认实现 onchange 事件,得到的结果就是当焦点失去,才会得到改变后的值。

结论

双向绑定是采用数据驱动的形式的最好体验,现在的前端框架都具备这项功能,监听输入的内容有变化就会立刻更新绑定变量的值,因此也减少了像JQ那样大量获取控件值的代码,我相信很多大型项目的开发人员深有体会。

为什么用 Blazor

Blazor 的优势就是在于用一套代码打造一个生态,至于现在很多前端框架,深沉的痛一般只有管理者才深有体会,因为他们需要考虑各种成本因素,特别是在对于不同语言学习、人员的配置、协调,特别是某项技能的人员离职以后的交接工作等等,都会花费大量的成本在里面,招聘其实很不容易的。