Blazor 西裝外套·佈雷澤

在Razor模板中使用html css來構建頁面
使用c#來編寫邏輯
將他們組合起來為組件

https://blazor-university.com/

組件

blazor的默認模板將組件放在Shared和Pages目錄下
Shared 表示公共組件
Pages 表示頁面組件

組件組成部分

組件主文件為.razor後綴的文件,比如 Index.razor
根據默認的規範如果編寫css樣式可命名為 Index.razor.css,vs根據規則會為你自動歸類
同樣的,邏輯文件為 Index.razor.cs
Index.razor.cs 裏的類名需要標記為 partial 與 Index.razor 打配合
比如: public partial class Index{} 如不想partial也可以使用繼承 @inherits來繼承一個新類,見下,

.razor 裏的內容

路由

@page "/todo"

@page "/todo/{Id}"partial
可以使用@code在當前頁面編寫,效果與上述新建的partial類一致

@code {

[Parameter]

public string Id { get; set; }

}

繼承 @inherits

繼承效果與partial代碼類似
在頁面使用 @inherits IndexBase 則可在頁面中訪問IndexBase類中的成員

public class IndexBase : ComponentBase{}

加載完畢事件

protected override async Task OnInitializedAsync(){}

參數賦值完事件會更加後延,等參數設置完畢再動手刷新界面可能會更準確
protected override void OnParametersSet()

參數

使用[Parameter]標記屬性為參數
當頁面被通過路由訪問或調用組件時賦值,則可以被傳遞參數(就是new完對象給屬性賦值)
@page "/todo/{Id}" 會傳遞id到

@code {
    [Parameter]
    public string Id { get; set; }
}

依賴注入

組件中注入

使用@inject ClassType varName 或者對屬性標記特性 [Inject] 可以注入服務
在使用前需要在Main方法中進行預先註冊

builder.Services.AddSingleton(typeof(YourClass)); //單例
builder.Services.AddScoped(typeof(YourClass)); //blazor裏的範圍與單例差不多
builder.Services.AddTransient(typeof(YourClass)); //瞬時,組件切換後消失
  • 非組件的【服務】注入需要在構造函數內進行
    (隨便寫個類它不會為你注入,.net的注入具有傳染性,必須是加入服務協會的類才會給你互相注入
    組件不需要手動加入,默認就是這個協會的
    )

數據綁定

單向綁定

直接使用@插值
<p>@Count</p>

雙向綁定

在有值輸入輸出的控件中
使用@bind進行單項綁定
使用@bind:event控制綁定觸發時機
<input @bind="MyValue" @bind:event="oninput" />

自定義組件屬性的雙向綁定

在自定義組件中定義屬性

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

定義回調屬性,名字需要按照規定來

[Parameter]
    public EventCallback<int> AgeChanged { get; set; }

在組件內部事件調用回調屬性來進行通知

await ShowChanged.InvokeAsync();

在外部使用雙向綁定

<UserInfo @bind-Age="屬性名"/>

事件傳參

委託
@onclick="@(()=>SetUserInfo(user))"
原生參數
public async Task SearchEnter(KeyboardEventArgs e)

內置組件

改變標題

<PageTitle>組件進入就改變當前標題</PageTitle>

表單驗證

用到在寫,也很簡單

js互操作

訪問js

[Inject]
public IJSRuntime JSRuntime { get; set; }
await JSRuntime.InvokeAsync<object>("localStorage.setItem", "key1", "value1");
var result = await JSRuntime.InvokeAsync<object>("localStorage.getItem", "key1");

如果要調用自定義的js函數,應該掛載到window下

window.areyouok = (name) => {return "ok"};

瀏覽器地址

blazor貌似目前還沒有hash路由
靜態部署時路由會有點小問題
在切換頁面後將瀏覽器地址改回基地址

@inject NavigationManager NavigationManager
@inject IJSRuntime JSRuntime

   var baseUrl = NavigationManager.BaseUri;
        var curUrl = NavigationManager.Uri;
        Console.WriteLine(baseUrl);
        Console.WriteLine(curUrl);

        //修改瀏覽器地址
        Task.Run(async () =>
        {
            await JSRuntime.InvokeAsync<object>("window.history.pushState", " ", " ", baseUrl); 
        });

實現 IDisposable

可以在組件銷燬時候執行代碼
根據此操作可以實現頁面狀態的保存,並在構造函數內進行加載(我自己這麼用的)

@implements IDisposable

...

@code {
    ...

    public void Dispose()
    {
        obj?.Dispose();
    }
}