Blazor 组件的初学者指南

在这里插入图片描述下载:


Blazor 组件概述

Blazor 组件是 UI 的一个独立部分,例如页面、侧边栏菜单、联系表单或仪表板小部件等。它包括用于呈现 UI 的 HTML 标记和用于处理数据或处理用户事件。组件可以相互嵌套,也可以在项目中甚至跨多个项目重复使用。 Blazor 组件是作为 Razor 组件实现的,这就是它们使用 Razor 语法并具有 .razor 文件扩展名的原因。在这里插入图片描述
要了解 Blazor 组件的结构及其工作原理,让我们回顾一下 Counter.razor 组件,如果您在 Visual Studio 2019 中使用 Blazor 应用模板,它会自动为我们生成。这是 Counter.razor 的完整代码。

@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++;
    }
}

文件中的第一行使用 Razor @page 指令,该行指定组件路由。这意味着 Counter 组件是页面级或可路由组件,可以在浏览器中使用 URL 末尾的 /counter 路径访问它。如果我们不指定@page 指令,则该组件将成为子组件,可以通过将其嵌入其他组件中来使用。

@page "/counter"

我们还可以声明多个@page 级别的指令,如下所示。这将允许我们使用两个 URL 访问组件。

@page “/counter”
@page “/mycounter”

在@page 指令之后,我们有 HTML 标记,用于指定组件的 UI。此标记可以使用表达式、条件或使用剃刀语法的循环来动态呈现 HTML。在上述 Counter 组件的情况下,UI 具有标题 (h1)、段落 (p) 和按钮元素。段落元素使用剃刀语法来输出 C# 代码块中定义的 currentCount 变量的值。

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

按钮元素通过调用 IncrementCount 方法来响应用户单击操作,该方法也在代码块中定义。

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

最后,我们有一个代码块,每次调用 IncrementCount 方法时,我们只是将 currentCount 变量的值加 1。

@code {
    private int currentCount = 0;
 
    private void IncrementCount()
    {
        currentCount++;
    }
}

当 Blazor 应用程序编译时,HTML 标记和 C# 代码将转换为名称将与文件名称匹配的组件类。这个类的成员将是我们在@code 块中定义的相同变量和方法。我们允许使用多个@code 块,所有这些代码块在编译后会合并为一个组件类。

在 Visual Studio 2019 中创建 Blazor 组件

如果要创建页面级组件,请右键单击 Pages 文件夹并选择 Add > Razor Component... 菜单选项。
在这里插入图片描述
您还可以在解决方案资源管理器中右键单击项目名称,然后使用 Razor 组件模板创建一个组件。在这里插入图片描述
让我们创建一个文件名为 Calculator.razor 的组件,并向其中添加以下代码。

Calculator.razor

@page "/calculator"
 
<h3>Calculator</h3>
 
<div class="form-group">
    <label for="number1">Number 1</label>
    <input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
    <label for="number2">Number 2</label>
    <input type="number" class="form-control" id="number2"  @bind="number2">
</div>
<div class="form-group">
    <label><b>Total: </b>@total</label> 
</div>
 
<button class="btn btn-primary" @onclick="Calculate">Calculate</button>
 
@code {
    private int number1 = 0;
    private int number2 = 0;
    private int total = 0;
 
    private void Calculate()
    {
        total = number1 + number2;
    }
}

@code 块有三个私有变量和一个计算方法。计算方法只是将 number1 和 number2 的总和保存在 total 变量中。

HTML 标记有两个输入字段,它们使用 @bind 属性来绑定 number1 和 number2 变量

<input type="number" class="form-control" id="number1" @bind="number1">

总变量值将使用razor语法@total 在页面上呈现

<label><b>Total: </b>@total</label> 

最后,我们有一个按钮元素,它将Calculate 方法与@onclick 事件绑定在一起。每当用户单击按钮时,Calculate 方法将被调用,并且 total 变量的值将在页面上更新。

<button class="btn btn-primary" @onclick="Calculate">Calculate</button>

为了使您的 Calculator 组件易于访问,您可以通过在 NavMenu.razor 组件中添加以下标记,在应用程序侧栏中添加您的 Calculator 组件。

<li class="nav-item px-3">
   <NavLink class="nav-link" href="calculator">
      <span class="oi oi-calculator" aria-hidden="true"></span> Calculator
   </NavLink>
</li>

按 F5 运行您的应用程序,您应该能够看到如下所示的页面。尝试在字段中输入一些数字,您应该能够看到页面上显示的数字的总和。按计算按钮运行服务器端 C# 代码,但没有浏览器回发或页面刷新。一切都感觉流畅而快速,就像您使用 JavaScript 在浏览器中进行计算一样。
在这里插入图片描述
如果您想获得代码在服务器端运行的感觉,只需尝试在计算方法中添加断点并再次按 F5。这次当您单击计算按钮时,您将看到代码执行在断点处停止,您还可以在工具提示中看到用户输入,如下所示。在这里插入图片描述

拆分 Blazor 组件标记和代码

如果您正在创建小组件,那么您可能希望在单个 .razor 文件中编写所有 C# 代码,但如果您有大量逻辑并且为了更好的代码维护,您希望将 C# 代码与 HTML 标记分开,那么您可以采用以下两种方法之一。

使用基类拆分组件

使用这种方法,您可以创建一个独立的类,该类应该从 ComponentBase 类派生。然后,您可以将组件属性和方法从 @code 块移动到这个新创建的类,最后,您可以使用 @inherits 指令来指定组件的基类。让我们将此方法应用于我们上面创建的计算器组件。在项目中创建一个类 CalculatorBase 并将 C# 代码从 Calculator.razor 移动到这个新类中。

CalculatorBase.cs

public class CalculatorBase : ComponentBase
{
    private int number1 = 0;
    private int number2 = 0;
    private int total = 0;
 
    private void Calculate()
    {
        total = number1 + number2;
    }
}

然后在 Calculator.razor 文件顶部添加 @inherits 指令,如下所示:

Calculator.razor

@page "/calculator"
@inherits CalculatorBase
 
<h3>Calculator</h3>
 
<div class="form-group">
    <label for="number1">Number 1</label>
    <input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
    <label for="number2">Number 2</label>
    <input type="number" class="form-control" id="number2"  @bind="number2">
</div>
<div class="form-group">
    <label><b>Total: </b>@total</label> 
</div>
 
<button class="btn btn-primary" @onclick="Calculate">Calculate</button>
 
@code {
     
}

如果此时您尝试构建应用程序,您会遇到很多错误,抱怨字段和方法的可访问性。
在这里插入图片描述以上所有错误都是因为Calculator组件继承自CalculatorBase类,而我们在CalculatorBase类中粘贴的属性和方法是私有的。为了确保子组件可以访问您的字段和方法,您需要将它们声明为 public。

public class CalculatorBase : ComponentBase
{
    public int number1 = 0;
    public int number2 = 0;
    public int total = 0;
 
    public void Calculate()
    {
        total = number1 + number2;
    }
}

使用分部类拆分组件

Blazor 组件作为分​​部类生成,这意味着我们可以创建一个与我们的组件同名的分部类,并在该分部类中移动所有 C# 代码。然后,此分部类将成为代码隐藏文件,并且该文件中声明的字段和属性将直接在 Blazor 组件中可用。让我们创建一个类 Calculator.razor.cs 并将我们的计算器代码放在这个新类中。

Calculator.razor.cs

public partial class Calculator
{
    public int number1 = 0;
    public int number2 = 0;
    public int total = 0;
 
    public void Calculate()
    {
        total = number1 + number2;
    }
}

如果启用了文件嵌套,您将看到 Visual Studio 将自动开始同时显示组件和代码隐藏文件。
在这里插入图片描述
再次运行应用程序,计算器应该以与以前相同的方式工作。在这里插入图片描述

创建和使用子组件

Blazor 子组件是没有 @page 指令的组件。这些组件可以使用标准 HTML 语法包含在其他组件中。然后我们可以通过在页面上添加组件来构建复杂的 UI,我们甚至可以在同一页面上拥有同一个子组件的多个实例。如果一个子组件应该在多个父组件或页面中重复使用,那么最好将它们放在 Shared 文件夹中。让我们在 Shared 文件夹中创建一个简单的 Heading.razor 子组件,并在其中添加以下代码。

Heading.razor

<h3>Calculator</h3>

接下来,将父 Calculator.razor 文件中的 h3 元素替换为 element。运行应用程序,您应该会在子组件中看到页面上呈现的 h3 标题。

Calculator.razor

@page "/calculator"
@inherits CalculatorBase
 
<Heading />
 
<div class="form-group">
    <label for="number1">Number 1</label>
    <input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
    <label for="number2">Number 2</label>
    <input type="number" class="form-control" id="number2"  @bind="number2">
</div>
<div class="form-group">
    <label><b>Total: </b>@total</label> 
</div>
 
<button class="btn btn-primary" @onclick="Calculate">Calculate</button>

您甚至可以通过复制和粘贴相同的元素来使用子组件的多个实例。

<Heading />
<Heading />
<Heading />

如果您现在运行您的应用程序,您将在页面上看到三个 h3 标题。在这里插入图片描述

使用参数自定义 Blazor 组件

总是生成相同内容的静态组件不会很有用。如果我们可以将一些数据传递给组件并不仅自定义它生成的 UI,还自定义其行为或功能,那就更好了。我们可以使用参数自定义 Blazor 组件。这些参数可以很简单,例如int, bool 或者它们也可以更复杂,例如Customer、Order 等。一旦声明了参数,我们就可以使用属性将数据传递给组件。让我们通过在 Heading 组件中声明一个简单的 Title 参数来学习这个概念。要指定参数,我们将 [Parameter] 属性附加到一个属性。

Heading.razor

<h3>@Title</h3>
 
@code {
    [Parameter]
    public string Title { get; set; } = "Default Title";
}

我们还使用默认字符串 Default Title 设置 Title 属性,如果未提供 Title,则将显示该字符串在这里插入图片描述
Visual Studio IntelliSense 还显示组件参数,这很有帮助,因为我们不需要记住参数。在这里插入图片描述我们可以通过将任何字符串作为 Title 传递来从外部自定义 Title,并且 Heading 组件将自动呈现传递给它的不同字符串。

<Heading Title="Calculator" /> 

在这里插入图片描述
我们还可以使用表达式从父组件到子组件传递数据。让我们创建另一个子组件 CalculatorTotal.razor 并向其添加以下代码。

CalculatorTotal.razor

<label><b>Total: </b>@Total</label>
 
@code {
    [Parameter]
    public int Total { get; set; }
}

现在,您可以使用我们在父计算器控制器中声明和设置的 @total 字段传递 Total 值。

Calculator.razor

@page "/calculator"
 
<Heading Title="Calculator" />
 
<div class="form-group">
    <label for="number1">Number 1</label>
    <input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
    <label for="number2">Number 2</label>
    <input type="number" class="form-control" id="number2" @bind="number2">
</div>
<div class="form-group">
    <CalculatorTotal Total="@total"/>
</div>
 
<button class="btn btn-primary" @onclick="Calculate">Calculate</button>

将路由参数传递给 Blazor 组件

Blazor 组件还可以接受来自 @page 指令中提供的路由模板的参数。路由器使用路由参数自动填充相应的组件参数。

让我们看一个如何将数据从路由传递给组件的示例。创建一个名为 MathTable.razor 的新 Blazor 组件并添加以下代码。

MathTable.razor

@page "/MathTable/{number:int}"
 
<h3>Math Table</h3>
 
<table class="table table-bordered w-25">
    @for (int i = 1; i <= 10; i++)
    {
        <tr>
            <td>@Number</td>
            <td>x</td>
            <td>@i</td>
            <td>=</td>
            <td>@(Number * i)</td>
        </tr>
    }
</table>
 
@code {
    [Parameter]
    public int Number { get; set; } 
}

我们指定了一个带有 int 参数号的路由模板

@page "/MathTable/{number:int}"

路由参数将自动与以下组件参数映射。

[Parameter]
public int Number { get; set; } 

在 HTML 标记中,我使用 number 参数生成数学表。运行项目并尝试在路由 URL 中传递不同的数字,您将看到根据参数值更新的数学表。
在这里插入图片描述

总结概括

在本教程中,我尝试介绍 Blazor 组件的基础知识。我试图用易于理解的示例来演示每个概念,以便您可以快速学习基本概念。 Blazor 组件提供的功能比我在本教程中介绍的要多得多,而且还有许多其他与 Blazor 组件相关的高级主题。

posted @ 2021-07-23 09:52  cool2feel  阅读(584)  评论(0编辑  收藏  举报