當我們在新增一個頁面時,可以設定這個頁面的路由,例如打開剛建立好的Blazor專案,開啟Page/Counter.razor,可以在第一行看到@page "/counter",這個就是Counter component的路由設定,讓我們可以透過http://localhost/counter 這個Url連到此頁。
Component的路由還可以設定從Url接參數,例如我們在@page "/counter"的下方再加一行@page "/counter/{id:int}",另外再設定一個屬性,就可以接收到該參數。
@page "/counter"
@page "/counter/{id:int}"
<h1>Counter</h1>
<h3>Current count: @id</h3>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
[Parameter]
public int id { get; set; }
private void IncrementCount()
{
id++;
}
}
在我們新增的這行路由可以看到{id:int},這是一個路由條件約束,表示id參數只能是int型別,如果參數是字串的話,則可以不用設定條件約束,而接收的屬性可設為string:
@page "/counter/{word}"
<h2>@word</h2>
@code {
[Parameter]
public string word { get; set; }
}
其他型別的條件約束可參考官方文件
我們可以一次設定多個路由給component,比方說在Count component的上方再加上一行@page "/mycounter",這樣我們在Url輸入http://localhost/counter 或 http://localhost/mycounter ,都可以連到counter component
接下來我們來看看Blazor處理路由的過程
Blazor是使用Router這個Component來處理路由的,它位在專案根目錄底下的App.razor。
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
當有一個Request過來時,Router的任務就是決定要載入哪一個component。以上述的counter為例,當我們傳送http://localhost:5001/counter 這個請求,Router就會開始透過AppAssembly來尋找是否有標註@page "/counter"的component,找到的話就會透過Found template處理,沒找到則會由NotFound template處理
Found template:
在Found中有個RouteView Component,透過routeData傳入路由參數,並且渲染counter component和它的Layout到頁面上,如果counter component沒有設定layout,那預設會使用DefaultLayout中的MainLayout。
NotFound template:
預設在MainLayout中顯示"Sorry, there's nothing at this address.",如果要自訂not found訊息,可以修改這個p標籤中的文字,或是換成自訂的component來顯示
這個NotFound template是一個自訂的404錯誤頁,當我們點擊畫面上的回首頁按鈕後,可以導回首頁:
@inject NavigationManager navigation
<div class="container">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="h5">404! This Is Custom Not Found Page</div>
</div>
<div class="card-footer">
<button class="btn btn-primary" @onclick="GoHome">Go Home</button>
</div>
</div>
</div>
</div>
</div>
@code {
private void GoHome()
{
navigation.NavigateTo("/");
}
}
畫面中的回首頁按鈕在click後,觸發GoHome方法的navigation.NavigateTo("/"),導至首頁。
@inject NavigationManager navigation 這行用意是從DI取得NavigationManager物件,讓我們可以透過這個物件來轉到其他頁面。
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<CustomNotFound />
</NotFound>
</Router>
NotFound template中換成剛剛做好的CustomNotFound Component就可以了