Blazor Server 从头开始:02 创建组件

🧭 系列导航

📖 阅读说明

此部分内容旨在说明各种Blazor的基本概念与使用方法,并没有提供实际的教程式代码,所以读者没必要把代码敲一遍。没得意义。

🔧 Razor 组件 

Razor组件是Blazor应用的基本单元,每一个页面或页面上的元素都可以是一个组件,或者说,可以将组件看成是一个页面或引用到一个页面的一部分。

Razor组件分成三个部分组成,

1)声明:@page  "路由名称" ,用于表示当前页面的路由;@layout 模板名称,表示当前组件使用哪个布局模板;@inherits LayoutComponentBase,表示当前组件是一个布局组件等。

2)页面:使用HTML语言进行描述,中间穿插一些Razor的模板语法,用来表示组件应该长什么样,都有什么元素。

3)逻辑:@code { ... } ,描述组件的交互逻辑,比如某个按钮的单击事件、页面数据的延迟加载、组件参数/属性等。

示例代码:

@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

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

@code {
    private int currentCount = 0;

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

🗺️ Blazor 基础路由

Blazor 通过路由组件<Router>将来自用户的请求路由到 Razor 组件。 <Router>组件在Blazor应用中的App组件内使用,默认会使用<Found>来描述可以找到路由信息时,如何进行处理,使用<NotFound>来描述找不到路由信息时,如何处理。

Blazor 路由用来将创建好的Razor组件与具体的URL绑定在一起。(这里与其他框架不同,路由的定义不是在一个单独的文件里面,而是在每个组件的声明部分,使用 @page "路由名称" 表示。

编译带有 @page 指令的 Razor 组件 (.razor) 时,将为生成的组件类提供一个 RouteAttribute 来指定组件的路由模板。

当应用启动时,将扫描指定为 路由器的 AppAssembly 的程序集,来收集具有 RouteAttribute 的应用组件的路由信息。

—— 《ASP.NET Core Blazor 路由和导航》

默认的 App 组件

 1 <Router AppAssembly="@typeof(App).Assembly">
 2     <Found Context="routeData">
 3         <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
 4         <FocusOnNavigate RouteData="@routeData" Selector="h1" />
 5     </Found>
 6     <NotFound>
 7         <PageTitle>Not found</PageTitle>
 8         <LayoutView Layout="@typeof(MainLayout)">
 9             <p role="alert">Sorry, there's nothing at this address.</p>
10         </LayoutView>
11     </NotFound>
12 </Router>
View Code

 

👗 Blazor 基础布局

与其他框架类似,Blazor可以将页面中的通用部分抽象成模板,然后放入到布局组件中。

在布局组件的声明部分,使用 @inherits LayoutComponentBase 表示当前组件是一个布局组件,然后就可以在其他的组件中使用  @layout 组件名称 来进行引用。

在布局组件的元素部分,可以编写使用此布局的组件的通用描述,比如左侧导航、底部说明等内容。然后使用 @body 表示引用此布局组件的页面组件的内容。

默认的 MainLayout.razor 组件

 1 @inherits LayoutComponentBase
 2 
 3 <div class="page">
 4     <div class="sidebar">
 5         <NavMenu />
 6     </div>
 7 
 8     <main>
 9         <div class="top-row px-4">
10             <a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
11         </div>
12 
13         <div class="content px-4">
14             @Body
15         </div>
16     </main>
17 </div>
View Code

 

带有导航组件引用的 MainLayout.razor 组件

 1 @inherits LayoutComponentBase
 2 
 3 <PageTitle>BlazorServerSample</PageTitle>
 4 
 5 <div class="page">
 6     <div class="sidebar">
 7         <NavMenu />
 8     </div>
 9 
10     <main>
11         <div class="top-row px-4">
12             <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
13         </div>
14 
15         <article class="content px-4">
16             @Body
17         </article>
18     </main>
19 </div>
View Code

 

导航组件

 1 <div class="top-row ps-3 navbar navbar-dark">
 2     <div class="container-fluid">
 3         <a class="navbar-brand" href="">BlazorServerSample</a>
 4         <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
 5             <span class="navbar-toggler-icon"></span>
 6         </button>
 7     </div>
 8 </div>
 9 
10 <div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
11     <nav class="flex-column">
12         <div class="nav-item px-3">
13             <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
14                 <span class="oi oi-home" aria-hidden="true"></span> Home
15             </NavLink>
16         </div>
17         <div class="nav-item px-3">
18             <NavLink class="nav-link" href="counter">
19                 <span class="oi oi-plus" aria-hidden="true"></span> Counter
20             </NavLink>
21         </div>
22         <div class="nav-item px-3">
23             <NavLink class="nav-link" href="fetchdata">
24                 <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
25             </NavLink>
26         </div>
27     </nav>
28 </div>
29 
30 @code {
31     private bool collapseNavMenu = true;
32 
33     private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
34 
35     private void ToggleNavMenu()
36     {
37         collapseNavMenu = !collapseNavMenu;
38     }
39 }
View Code

 

布局组件可以嵌套多层使用,还可以通过在文件夹内创建 _Imports.razor 组件来描述(@layout 组件名称)当前文件夹中所有的组件的默认布局文件。

 

 

 

如果想要更改MainLayout.razor的位置(比如将其移动到我们自定义的专门用于放各种通用布局和模板文件的Shared文件夹中),需要更改项目根目录下的 _Imports.razor 文件,在其中加上对新建文件夹的应用。

 

 

 

🤔 总结思考

  • Blazor Server 与Blazor WebAssembly 在路由和导航上的一些用法是不同的,所以当需要使用Blazor WebAssembly时,可能需要重新学习相关部分内容;
  • Blazor的布局直观感受并不是特别的灵活,或许因为时间太短没有学习或领会到更加其灵活的地方;
  • 因为 _Imports.razor 组件的存在,直观上考虑,利用文件夹将具有相关性的组件组织起来比较好,这样或许会大量减少对于布局组件的引用。

 

posted @ 2022-12-26 15:55  Margin22  阅读(372)  评论(0编辑  收藏  举报