Skip to content

第十三章:Blazor WebAssembly UI 開發

13.1 引言:C# 全端開發的夢想

Blazor WebAssembly (WASM) 允許開發者使用 C# 而非 JavaScript 來編寫前端應用程式。這對於 .NET 開發者來說是一個巨大的優勢,因為我們可以:

  1. 共用 DTO 與邏輯:前後端共用 Application.ContractsDomain.Shared
  2. 強型別開發:享受編譯器檢查與 IntelliSense。
  3. 統一技術堆疊:不需要學習 React/Angular/Vue。

ABP Framework 為 Blazor 提供了深度的整合,包括預建的 UI 元件、自動授權與多語言支援。


13.2 專案結構與啟動

當您使用 -u blazor 建立專案時,會多出一個 Blazor 專案。

1. Blazor 專案結構

  • Program.cs:設定 WASM 宿主、註冊服務 (DI)。
  • App.razor:路由入口。
  • Menus/:定義選單結構。
  • Pages/:Razor 頁面元件。

2. Blazorise 元件庫

ABP 社群版預設使用 Blazorise 作為 UI 框架 (通常搭配 Bootstrap 5 提供者)。

  • 優勢:跨 CSS 框架的抽象層。您可以切換底層 CSS (Bootstrap, Bulma, AntDesign) 而不需修改 Razor 程式碼。
  • V10.0 更新:升級至 Blazorise 1.8.6,帶來了更多的元件與效能改進。

13.3 開發 Blazor 頁面

1. 頁面定義 (@page)

csharp
@page "/books"
@using Volo.Abp.Application.Dtos
@inherits AbpCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>
  • 繼承基類AbpCrudPageBase 是一個強大的基類,它內建了 CRUD 所需的大部分邏輯 (載入列表、分頁、排序、建立/編輯 Modal 控制)。

2. 注入服務 (@inject)

csharp
@inject IBookAppService BookAppService
@inject IStringLocalizer<BookStoreResource> L

3. 使用 Blazorise 元件

html
<Card>
  <CardHeader>
    <Row Class="justify-content-between">
      <Column ColumnSize="ColumnSize.IsAuto">
        <h2>@L["Books"]</h2>
      </Column>
      <Column ColumnSize="ColumnSize.IsAuto">
        <button Color="Color.Primary" Clicked="OpenCreateModalAsync">
          <Icon Name="IconName.Add" /> @L["NewBook"]
        </button>
      </Column>
    </Row>
  </CardHeader>
  <CardBody>
    <DataGrid
      TItem="BookDto"
      Data="Entities"
      ReadData="OnDataGridReadAsync"
      TotalItems="TotalCount"
      ShowPager="true"
      PageSize="PageSize"
    >
      <DataGridColumn TItem="BookDto" Field="@nameof(BookDto.Name)"
      Caption="@L["Name"]" /> <DataGridColumn TItem="BookDto"
      Field="@nameof(BookDto.Price)" Caption="@L["Price"]" />
      <DataGridEntityActionsColumn TItem="BookDto" @ref="EntityActionsColumn">
        <DisplayTemplate>
          <EntityActions
            TItem="BookDto"
            EntityActionsColumn="@EntityActionsColumn"
          >
            <EntityAction TItem="BookDto" Text="@L["Edit"]" Clicked="() =>
            OpenEditModalAsync(context)" /> <EntityAction TItem="BookDto"
            Text="@L["Delete"]" Clicked="() => DeleteEntityAsync(context)"
            ConfirmationMessage="Are you sure?" />
          </EntityActions>
        </DisplayTemplate>
      </DataGridEntityActionsColumn>
    </DataGrid>
  </CardBody>
</Card>
  • DataGrid:Blazorise 的核心元件,支援分頁、排序、篩選。
  • EntityActions:ABP 封裝的下拉選單,用於操作單一列。

13.4 狀態管理與資料流

1. C# API 代理 (C# API Proxies)

與 MVC 的 JS Proxy 類似,ABP 也為 Blazor 生成了 C# Proxy。

  • HttpApi.Client 專案:負責生成這些 Proxy。
  • 使用方式:直接注入介面 IBookAppService。在執行時,它會透過 HttpClient 發送 REST 請求到後端 API。

2. 授權 (Authorization)

ABP Blazor 範本整合了 Microsoft.AspNetCore.Components.WebAssembly.Authentication

  • AccessToken:自動附加到每個 HTTP 請求的 Header 中。
  • AuthorizeView
    html
    <AuthorizeView Policy="BookStore.Books.Create">
      <Authorized>
        <button ...>Create</button>
      </Authorized>
    </AuthorizeView>

13.5 效能優化技巧

Blazor WASM 的主要缺點是 首次載入時間 (Initial Load Time)

1. 延遲載入 (Lazy Loading)

將不常用的模組 (如 Admin 頁面) 設定為延遲載入。ABP 支援模組級別的延遲載入。

2. 減少傳輸量

  • 使用 Brotli 壓縮 (預設開啟)。
  • 移除不必要的 NuGet 套件引用。

3. 虛擬化 (Virtualization)

對於長列表,使用 <Virtualize> 元件,只渲染可見區域的項目。

html
<Virtualize Items="@AllBooks" Context="book">
  <tr>
    <td>@book.Name</td>
  </tr>
</Virtualize>

13.6 實戰練習

練習 1:建立 CRUD 頁面

  1. 建立 Books.razor
  2. 繼承 AbpCrudPageBase
  3. 使用 DataGrid 顯示書籍列表。
  4. 實作 CreateModalEditModal (使用 Modal 元件)。

練習 2:實作權限控制

  1. Books.razor 上方加入 @attribute [Authorize("BookStore.Books")]
  2. 在 "新增按鈕" 外圍包裹 <AuthorizeView Policy="BookStore.Books.Create">
  3. 使用不同權限的使用者登入測試。

練習 3:自訂元件

  1. 建立一個 BookCard.razor 元件,用於以卡片形式顯示書籍資訊。
  2. 定義 [Parameter] public BookDto Book { get; set; }
  3. Books.razor 中使用此元件。

13.7 總結

Blazor WebAssembly 讓 .NET 開發者能以熟悉的語言構建現代化的 SPA。

  • Blazorise 提供了豐富的 UI 元件。
  • AbpCrudPageBase 大幅簡化了 CRUD 開發。
  • C# Proxy 讓前後端通訊變得透明。

至此,我們已經涵蓋了 ABP 的兩種主要 UI 模式 (MVC 與 Blazor)。在接下來的 第四部:進階架構 中,我們將探討微服務、模組化開發與多租戶等進階主題。


參考資源

Released under the MIT License.