[AspNetCore 3.0] 在RazorPages/MVC 中使用 Blazor (Razor組件)
- 2019 年 10 月 3 日
- 筆記
開發環境
Vs2019 16.3.1 dotnetcore 3.0
一、開始
- 新建webapp項目
dotnet new webapp -o projectname
或Vs 中新建項目選擇 Web應用程序。
在StartUp.cs 中增加兩處配置。
ConfigureServices 方法:
public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddServerSideBlazor();//啟用服務端blazor支持 }
Configure 方法
app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapBlazorHub();// js,singalr });
-
使用Vs打開項目,默認頁面和目錄暫時不動, 新增文件夾 RazorComponents
-
在項目根目錄下,右鍵菜單添加-新建項-Razor組件,命名
_Imports.razor
,用於導入razor組件所需命名空間(作用類似mvc中的_ViewImports.cshtml)。
此文件對同級或子級文件夾中的*.razor生效, 將內容替換為
@using Microsoft.AspNetCore.Components @using Microsoft.AspNetCore.Components.Web;
-
在RazorComponents 文件夾上 右鍵菜單添加-新建項-Razor組件,命名
CounterButton.razor
。
二、 組件 CounterButton.razor
說明:
- 呈現為html button 元素 ,顯示當前計數。
- 用戶單擊按鈕時回傳給服務端,將計數+1,隨後更新客戶端文本。
-
CounterButton.razor
.razor文件本質為一個繼承ComponentBase,名為CounterButton的c#類(全名為項目名稱.文件夾.CounterButton)。
打開CounterButton.razor 文件可以看到,@code指令(預覽6之前的@functions)將文件分為兩部分,上部為html標籤,下部即為CounterButton類的實現部分。
CounterButton.razor<h3>Component</h3> @code {//可腦補為 public class CounterButton:ComponentBase{ //c#代碼,屬性、方法。。 }
- 處理c#代碼:
增加屬性 Count,增加方法 Click
[Parameter]// 用於傳遞參數 public int Count { get; set; } void Click() { Count++; }
-
處理Html標記, CounterButton.razor 內容如下
<button @onclick="Click" > Count:@Count </button> @code { [Parameter] public int Count { get; set; } void Click() { Count++; } }
此時組件代碼已完成,接下來轉到Pages目錄下,處理.cshtml
三、在.cshtml中使用
-
打開Pages/Index.cshtml,在你想要顯示組件的地方插入代碼
@(await Html.RenderComponentAsync<RazorComponents.CounterButton>(RenderMode.Server))
- RenderMode 說明
- 如果在Pages/_ViewImports.cshtml 加入using projectname.RazorComponents 調用如下
@(await Html.RenderComponentAsync<CounterButton>(RenderMode.Server))
- 打開Pages/Shared/_Layout.cshtml, 加入
<script src="_framework/blazor.server.js"></script>
- 保證此腳本在組件render 位置之後加入
- 啟動項目,打開瀏覽器,點擊 button 查看效果。
- 打開瀏覽器調試窗口-networks選項卡,其中 以_blazor開頭的即為組件使用的signalR連接
四、使用組件參數
在之前的組件代碼中有這樣一行
[Parameter]// 用於傳遞參數 public int Count { get; set; }
可以用來設置初始化參數,如果在另一個.razor 文件中,我們可以這樣設置 Count的初始值
<CounterButton Count="2" />
但是,使用Html.RenderComponentAsync 時, RenderMode 為Server或ServerPrerendered 不支持參數。RenderMode.Static 僅輸出靜態Html(無法與服務端交互)。
在目前階段,我們可以使用一個無參數的razor組件過渡一下。
- 在項目中新增razor組件 『RazorPanel.razor』,為了演示,將此組件加到項目根目錄下。
- 代碼如下
//根據業務,將需要組合的razor組件放在一個組件內,可以方便的處理參數及組件間的關係 <CounterButton Count="3"/>// 在_Imports.razor 中加入@using projectname.RazorComponents 或使用全名<projectname.RazorComponents.CounterButton Count="3"/>
- 修改組件調用
@(await Html.RenderComponentAsync<RazorPanel>(RenderMode.Server))
五 直接繼承ComponentBase 實現組件
前面說過,組件是繼承 ComponentBase的,因此可以用一個c#代碼文件實現組件,以下以Icon為例。
- 此Icon組件使用svg use方式,對應的js 定義來自[iconfont.cn]
- 新建組件 ‘Icon.razor’.
- 新建c#類 ‘Icon.razor.cs’.
public class IconBase: Microsoft.AspNetCore.Components.ComponentBase { [Parameter] public string IconName { get; set; } = "icon-user"; [Parameter] public string IconClass { get; set; } = "icon"; }
- 文件名可以隨意,使用*.razor.cs 格式 vs會幫你將.cs和對應的.razor組織在一起。
- 打開 Icon.razor,清除自動生成的內容,在第一行加入
@inherits IconBase
完整代碼
@inherits IconBase <svg class="@IconClass" aria-hidden="true"> <use href="#@IconName"></use> </svg> <style scoped> .icon { height: 1em; /* 通過設置 font-size 來改變圖標大小 */ width: 1em; /* 圖標和文字相鄰時,垂直對齊 */ vertical-align: -0.15em; /* 通過設置 color 來改變 SVG 的顏色/fill */ fill: currentColor; /* path 和 stroke 溢出 viewBox 部分在 IE 下會顯示 normalize.css 中也包含這行 */ overflow: hidden; } </style>
- 目前.razor 自動生成的類 為 class Icon 而不是 partial class Icon ,因此.cs 文件里的類名不能是Icon。也只能通過 @inherits 關聯 .razor 里的html和c#代碼。
- .razor 看起來和vue組件有點類似
- @if @foreach 等指令見文檔
- use標籤中使用 href
- 在Pages/Shared/_Layout.cshtml 引入從[iconfont.cn]下載的js(通常為 iconfont.js);
- 在 RazorPanel.razor 中加入Icon :`
六 組件嵌套
razor組件上可以使用ChildContent 屬性嵌套其他組件,比如需要在CounterButton中加入一個Icon.
-
在CounterButton.razor 中增加一個屬性
[Parameter] public RenderFragment ChildContent { get; set; }
- 修改html 部分
<button @onclick="Click"> @ChildContent Count:@Count </button>
-
打開RazorPanel.razor,修改 CounterButton 標記
<CounterButton Count="3"> <ChildContent> <Icon IconName="icon-user" /> </ChildContent> </CounterButton>
或 省略<ChildContent>
<CounterButton Count="3" > <Icon IconName="icon-user" /> </CounterButton>
七 組件引用
在想引用的子組件上定義 @ref ="組件引用名",在當前組件上定義同名字段捕獲引用。
比如 在 RazorPanel.razor 中,給CounterButton 增加屬性
<CounterButton Count="3" @ref="button" > <Icon IconName="icon-user" /> @button.Count </CounterButton>
@code
CounterButton button;//自動捕獲 @ref="button" 的CounterButton 實例
其他
- 手工處理html標記
使用 RenderTreeBuilder 上的方法處理標記,注意序號。
RenderFragment 委託,ComponentBase.BuildRenderTree 方法
- 在cshtml 上渲染.razor 組件時,使用類似 RazorPanel 之類的容器來處理參數傳遞。
- Microsoft.AspNetCore.Components.* 包括一些內置組件(Forms,Input*,Layout…)
- 官方模板
dotnet new -i Microsoft.AspNetCore.Blazor.Templates