.NET8 Blazor 從入門到精通:(二)組件

来源:https://www.cnblogs.com/timefiles/p/18362903
-Advertisement-
Play Games

目錄Blazor 組件基礎路由導航參數組件參數路由參數生命周期事件狀態更改組件事件 Blazor 組件 基礎 新建一個項目命名為 MyComponents ,項目模板的交互類型選 Auto ,其它保持預設選項: 客戶端組件 (Auto/WebAssembly): 最終解決方案裡面會有兩個項目:伺服器 ...


目錄

Blazor 組件

基礎

新建一個項目命名為 MyComponents ,項目模板的交互類型選 Auto ,其它保持預設選項:
image

客戶端組件 (Auto/WebAssembly):
最終解決方案裡面會有兩個項目:伺服器端項目客戶端項目,組件按存放項目的不同可以分為以下兩種組件:

  • 伺服器端組件:

    • 主要用於伺服器端渲染(SSR)
    • 被放置在伺服器端項目中
    • 適用於不需要實時交互或複雜用戶交互的場景
  • 客戶端組件 (Auto/WebAssembly):

    • 組件位於客戶端項目內
    • 使用 WebAssembly 技術進行編譯,能夠直接與瀏覽器交互
    • 適合需要交互性和實時更新的應用場景
    • 使用 SignalR 可以實現實時通信,從而增強組件的功能性

兩種組件選擇原則如下:

  • 如果組件不需要交互性,將其作為伺服器端渲染的組件。
  • 如果組件需要交互性(例如響應用戶的輸入、實時數據更新等),則應該考慮將其作為客戶端組件,可以利用 SignalR 提供的實時通信功能。

在客戶端項目中新建一個 Demo 組件:

<!-- 選擇 Auto 或 WebAssembly ,否則無法交互 -->
@rendermode InteractiveAuto

<h3>Demo</h3>

<!-- 文本不為空時才顯示標簽 -->
@if (textInfo is not null)
{
    <h4>Info: @textInfo</h4>
}

<!-- 按鈕樣式參考 Counter 組件 -->
<button class="btn btn-primary" @onclick="UpdateText">Update Text</button>
<!-- 委托方式調用方法,可以傳入參數 -->
<button class="btn btn-primary" @onclick="(()=>{UpdateNumber(10);})">Update Number</button>


@code {
    private string? textInfo = null;

    private void UpdateText()
    {
        textInfo = "This is the new information";
    }

    private void UpdateNumber(int i = 0)
    {
        textInfo = $"This is number {i}";
    }
}

在伺服器端項目中的 Home 頁面中引用 Demo 組件:

@page "/"

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<Demo />

在 _Imports.razor 中引用 Demo 組件的命名空間:

@using MyComponents.Client.Pages

路由導航

在客戶端項目中添加一個 Start 組件,razor 代碼如下:

@*組件可以同時有多個路由*@
@page "/page"
@page "/pages/start"

@*可以使用組件名作路由*@
@attribute [Route(nameof(Start))]

@*頁面跳轉必須指定交互性,並註入導航管理器*@
@rendermode InteractiveAuto
@inject NavigationManager Navigation

<h3>Start</h3>

@*通過NavigationManager.NavigateTo方法跳轉到Counter組件*@
<button class="btn btn-primary" onclick="@(()=>Navigation.NavigateTo(nameof(Counter)))">Go to Counter</button>

@*執行完整的頁面重新載入*@
<button class="btn btn-primary" onclick="@(()=>Navigation.Refresh(true))">Refresh</button>
@code {

}

上面的代碼演示瞭如何使用路由和導航管理器進行頁面跳轉,組件可以同時有多個路由,也可以使用組件名作路由
跳轉到其它組件時會用到增強導航,參考 增強的導航和表單處理

參數

組件參數

在客戶端項目中添加一個 BetterCounter 組件,razor 代碼如下:

@rendermode InteractiveAuto

<h3>BetterCounter</h3>
<p role="status">Current count: @CurrentCount</p>

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

@code {

    //將目標成員表示為組件參數
    [Parameter]
    public int CurrentCount { get; set; }

    private void IncrementCount()
    {
        CurrentCount++;
    }
}

組件參數將數據傳遞給組件,使用組件類中包含 [Parameter] 特性的公共 C# 屬性進行定義,參考組件參數單向綁定

使用組件時需要將目標成員作為組件參數傳遞給組件,如在 Home 頁面中引用 BetterCounter 組件:

<BetterCounter CurrentCount="100" />
<!-- 或 -->
<BetterCounter CurrentCount=@currentCount />

路由參數

路由器使用路由參數以相同的名稱填充相應的組件參數,路由參數名不區分大小寫,參考文檔 路由參數

在 BetterCounter 組件的 razor 代碼中添加如下路由:

@*路由參數(無約束)*@
@page "/BetterCounter/{CurrentCount}"

@*路由參數約束*@
@page "/BetterCounter/{CurrentCount:int}"

@*可選路由參數(與上面任意一個路由搭配使用實現可選效果)*@
@page "/BetterCounter"

為了實現可選路由參數,需要在組件中添加一個預設值:

//將目標成員表示為組件參數
//需要將參數屬性的類型更改為可為 null,這樣就可以分辨出它是否被指定了值
[Parameter]
public int? CurrentCount { get; set; }

//為可選參數指定預設值    
protected override void OnInitialized()
{
    base.OnInitialized();    
    CurrentCount = CurrentCount ?? 1;
}

添加一個 Titlet 成員來接受查詢字元串的參數:


//指定組件參數來自查詢字元串
//路由:/BetterCounter?Titlet=asd
[SupplyParameterFromQuery]
public string? Titlet { get; set; } = "BetterCounter";
  • 路由參數:在添加組件的 @page 聲明時,通過將路由參數的名稱括在一對 { 大括弧 } 中,在URL中定義了路由參數,參考示例 路由參數

  • 路由參數約束:以冒號為尾碼,然後是約束類型,約束類型參考文檔 路由約束。以路由 /BetterCounter/abs 為例:

    • 沒有路由約束時會報類型轉換異常(字元串無法轉為int類型)
    • 有路由約束時會顯示404錯誤(沒有匹配到該 URL)
  • 可選路由參數:Blazor不明確支持可選路由參數,但通過在組件上添加多個 @page 聲明,可以輕鬆實現等效的路由參數,參考文章 可選路由參數

  • 查詢字元串:使用 [SupplyParameterFromQuery] 屬性指定組件參數來自查詢字元串,更多應用場景參考文檔 查詢字元串

生命周期事件

以下簡化圖展示了 Razor 組件生命周期事件處理,參考文檔 生命周期事件

image

在 Counter 組件中添加日誌記錄,觀察組件的生命周期:

@inject ILogger<Counter> log

//...

@code {
    //...
    protected override void OnInitialized()
    {
        log.LogInformation($"Initialized at {DateTime.Now}");
    }
    protected override void OnParametersSet()
    {
        log.LogInformation($"ParametersSet at {DateTime.Now}");
    }
    protected override void OnAfterRender(bool firstRender)
    {
        log.LogInformation("OnAfterRender: firstRender = {FirstRender}", firstRender);
    }
}
  • 組件初始化 (OnInitialized{Async}) :專門用於在組件實例的整個生命周期內初始化組件,參數值和參數值更改不應影響在這些方法中執行的初始化。

  • 設置參數之後 (OnParametersSet{Async}):在 OnInitialized 或 OnInitializedAsync 中初始化組件後或父組件重新呈現並變更參數時調用。

  • 組件呈現之後 (OnAfterRender{Async}):OnAfterRender 和 OnAfterRenderAsync 組件以交互方式呈現,併在 UI 已完成更新(例如,元素添加到瀏覽器 DOM 之後)後調用。OnAfterRender 和 OnAfterRenderAsync 的 firstRender 參數:

    • 在第一次呈現組件實例時設置為 true。
    • 可用於確保初始化操作僅執行一次。

運行後導航到Counter界面,控制台輸出如下:
image

狀態更改

StateHasChanged 通知組件其狀態已更改。 如果適用,調用 StateHasChanged 會導致組件重新呈現

將自動為 EventCallback 方法調用 StateHasChanged,也可以根據實際需求在組件中手動調用 StateHasChanged:

private async void IncrementCount()
{
    currentCount++;
    await Task.Delay(1000);
    StateHasChanged();

    currentCount++;
    await Task.Delay(1000);
    StateHasChanged();

    currentCount++;
    await Task.Delay(1000);
    StateHasChanged();
}

上面的代碼,如果不調用 StateHasChanged 則點擊後只會顯示 1 ,用 StateHasChanged 後則會依次顯示 1 2 3 。

組件事件

嵌套組件的常見方案是在發生子組件事件時在父組件中執行某個方法(如子組件中的 onclick 事件),跨組件公開事件請使用 EventCallback ,父組件可向子組件的 EventCallback 分配回調方法。

在 Counter 組件中添加一個事件:

@code {
    private int currentCount = 0;

    //定義一個事件回調參數
    [Parameter]
    public EventCallback<int> OnCounterChange { get; set; }

    private async Task IncrementCount()
    {
        currentCount++;
        //觸發事件回調
        await OnCounterChange.InvokeAsync(currentCount); 
    }
}

在另一個客戶端組件為 Counter 組件的事件分配回調方法(服務端組件會報錯):

<Counter OnCounterChange="UpdateCounter" />

@code {
    private int currentCount = 0;
    private void UpdateCounter(int val)
    {
        currentCount = val;
    }
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大家好,我是曉凡。 寫在前面 不知道大家有沒有做財務的朋友,我就有這麼一位朋友就經常跟我抱怨。一到月底簡直就是噩夢,總有加不完的班,熬不完的夜,做不完的報表。 一聽到這兒,這不就一活生生的一個“大表哥”麽,這加班跟我們程式員有得一拼了,忍不住邪惡一笑,心裡平衡了很多。 身為牛馬,大家都不容易啊。我不 ...
  • 目錄Razor 類庫創建使用使可路由組件可從 RCL 獲取靜態資源表單EditForm標準輸入組件驗證HTML 表單 Razor 類庫 這裡只對 RCL 創建和使用的做一些簡單的概述,詳細內容參考官方文檔 使用 Razor 類庫 (RCL) 中的 ASP.NET Core Razor 組件。 創建 ...
  • 泛型(Generics)是C#中的一個重要特性,它允許您編寫靈活、類型安全且可重用的代碼。下麵我將詳細介紹泛型的概念、使用方法及其在C#中的實現細節。 泛型的基本概念 1. 什麼是泛型? 泛型是一種允許您定義類型參數的機制,這些類型參數可以在編譯時由具體的類型替換。這樣,您可以編寫一個通用的類或方法 ...
  • VS常用拓展以及快捷鍵 擴展1:Select Next Occurrence 該拓展可以當前目標、下一個目標、上一個目標,類似於Alt+滑鼠拖動,但是可以在沒對齊的情況下使用 安裝 設置4個常用的快捷鍵 工具->選項->鍵盤->c# 2005 選擇下一個 快捷鍵:Ctrl+D 選擇上一個 快捷鍵:C ...
  • 編程編的久了,總會遇到多線程的情況,有些時候我們要幾個線程合作完成某些功能,這時候可以定義一個全局對象,各個線程根據這個對象的狀態來協同工作,這就是基本的線程同步。 支持多線程編程的語言一般都內置了一些類型和方法用於創建上述所說的全局對象也就是鎖對象,它們的作用類似,使用場景有所不同。.Net中這玩 ...
  • 我們.NET開發會引用很多外部Nuget包,多項目、多個解決方案、甚至多個倉庫。 簡單的Nuget包管理,通過VS就能比較簡單處理好。但複雜的場景呢,比如: 1.一個倉庫里,有多個解決方案的Nuget包管理 -- 我現在項目就是這樣的,針對會議大屏的全家桶軟體集代碼倉庫。這個倉庫里,接近30個工具/ ...
  • 在編寫上位機軟體時,需要經常處理命令拼接與其他設備進行通信,通常對不同的命令封裝成不同的方法,擴展稍許麻煩。 本次擬以特性方式實現,以兼顧維護性與擴展性。 思想: 一種命令對應一個類,其類中的各個屬性對應各個命令段,通過特性的方式,實現其在這包數據命令中的位置、大端或小端及其轉換為對應的目標類型; ...
  • 先看一下效果吧: isChecked = false 的時候的效果 isChecked = true 的時候的效果 然後我們來實現一下這個效果吧 第一步:創建一個空的wpf項目; 第二步:在項目裡面添加一個checkbox <Grid> <CheckBox HorizontalAlignment=" ...
一周排行
    -Advertisement-
    Play Games
  • 前言 推薦一款基於.NET 8、WPF、Prism.DryIoc、MVVM設計模式、Blazor以及MySQL資料庫構建的企業級工作流系統的WPF客戶端框架-AIStudio.Wpf.AClient 6.0。 項目介紹 框架採用了 Prism 框架來實現 MVVM 模式,不僅簡化了 MVVM 的典型 ...
  • 先看一下效果吧: 我們直接通過改造一下原版的TreeView來實現上面這個效果 我們先創建一個普通的TreeView 代碼很簡單: <TreeView> <TreeViewItem Header="人事部"/> <TreeViewItem Header="技術部"> <TreeViewItem He ...
  • 1. 生成式 AI 簡介 https://imp.i384100.net/LXYmq3 2. Python 語言 https://imp.i384100.net/5gmXXo 3. 統計和 R https://youtu.be/ANMuuq502rE?si=hw9GT6JVzMhRvBbF 4. 數 ...
  • 本文為大家介紹下.NET解壓/壓縮zip文件。雖然解壓縮不是啥核心技術,但壓縮性能以及進度處理還是需要關註下,針對使用較多的zip開源組件驗證,給大家提供個技術選型參考 之前在《.NET WebSocket高併發通信阻塞問題 - 唐宋元明清2188 - 博客園 (cnblogs.com)》講過,團隊 ...
  • 之前寫過兩篇關於Roslyn源生成器生成源代碼的用例,今天使用Roslyn的代碼修複器CodeFixProvider實現一個cs文件頭部註釋的功能, 代碼修複器會同時涉及到CodeFixProvider和DiagnosticAnalyzer, 實現FileHeaderAnalyzer 首先我們知道修 ...
  • 在軟體行業,經常會聽到一句話“文不如表,表不如圖”說明瞭圖形在軟體應用中的重要性。同樣在WPF開發中,為了程式美觀或者業務需要,經常會用到各種個樣的圖形。今天以一些簡單的小例子,簡述WPF開發中幾何圖形(Geometry)相關內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 在 C# 中使用 RabbitMQ 通過簡訊發送重置後的密碼到用戶的手機號上,你可以按照以下步驟進行 1.安裝 RabbitMQ 客戶端庫 首先,確保你已經安裝了 RabbitMQ 客戶端庫。你可以通過 NuGet 包管理器來安裝: dotnet add package RabbitMQ.Clien ...
  • 1.下載 Protocol Buffers 編譯器(protoc) 前往 Protocol Buffers GitHub Releases 頁面。在 "Assets" 下找到適合您系統的壓縮文件,通常為 protoc-{version}-win32.zip 或 protoc-{version}-wi ...
  • 簡介 在現代微服務架構中,服務發現(Service Discovery)是一項關鍵功能。它允許微服務動態地找到彼此,而無需依賴硬編碼的地址。以前如果你搜 .NET Service Discovery,大概率會搜到一大堆 Eureka,Consul 等的文章。現在微軟為我們帶來了一個官方的包:Micr ...
  • ZY樹洞 前言 ZY樹洞是一個基於.NET Core開發的簡單的評論系統,主要用於大家分享自己心中的感悟、經驗、心得、想法等。 好了,不賣關子了,這個項目其實是上班無聊的時候寫的,為什麼要寫這個項目呢?因為我單純的想吐槽一下工作中的不滿而已。 項目介紹 項目很簡單,主要功能就是提供一個簡單的評論系統 ...