不奇怪,我以前也这么做过。
您也不需要构建新的路由器。您可以将自定义路由器添加到NotFound
标准路由器的部分。
以下是具体操作方法。
我用过一个<string, Type>
字典。
首先是准系统定制路线服务
public class CustomRouteService
{
private List<CustomRouteData> _pages = new();
public IEnumerable<CustomRouteData> Pages => _pages.AsEnumerable();
public bool TryAddRoute(CustomRouteData data)
{
var isComponent = typeof(IComponent).IsAssignableFrom(data.Page);
var newRoute = !_pages.Any(item => item.Route.Equals(data.Route, StringComparison.CurrentCultureIgnoreCase));
if (isComponent && newRoute)
{
_pages.Add(data);
return true;
}
return false;
}
public bool TryAddRoute(string route, string className)
{
var page = Type.GetType(className);
if (page is null)
return false;
return this.TryAddRoute(new CustomRouteData(route, page));
}
public bool TryGetRoute(string route, out Type? page)
{
page = null;
var data = _pages.FirstOrDefault(item => item.Route.Equals(route, StringComparison.CurrentCultureIgnoreCase));
if (data is not null)
page = data.Page;
return page != null;
}
}
public record CustomRouteData(string Route, Type Page);
注册为单例服务
Next a CustomRouteLoader
剃刀组件。
@if (_isRoute)
{
<RouteView RouteData=_routeData DefaultLayout="@typeof(MainLayout)" />
}
else
{
@this.NotFound
}
@code {
[Parameter] public RenderFragment? NotFound { get; set; }
[Inject] public NavigationManager NavManager { get; set; } = default!;
[Inject] public CustomRouteService PageService { get; set; } = default!;
private Type? _component;
private bool _isRoute;
private RouteData? _routeData;
protected override void OnParametersSet()
{
_routeData = null;
// Get rhe route Uri
var url = this.NavManager.Uri.Replace(NavManager.BaseUri, "/");
// Try to get the component associated with the route
PageService.TryGetRoute(url, out _component);
// Check we have a type and it implements IComponent
_isRoute = _component is not null && typeof(IComponent).IsAssignableFrom(_component);
// Create the RouteData
if (_isRoute && _component is not null)
_routeData = new RouteData(_component, new Dictionary<string, object>());
}
}
将其添加到App
:
Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<CustomRouteLoader>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</CustomRouteLoader>
</NotFound>
</Router>
以及一个用于添加并导航到自定义路线的测试页面
@page "/"
@inject CustomRouteService customRouteService
@inject NavigationManager navManager
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
<button class="btn btn-success" @onclick=this.AddRoute>Add Fred Route</button>
<button class="btn btn-dark" @onclick=this.Navigate>Navigate to Fred</button>
<button class="btn btn-success" @onclick=this.AddJonRoute>Add Jon Route</button>
<button class="btn btn-dark" @onclick=this.NavigateJon>Navigate to Jon</button>
@code {
private void AddRoute()
=> customRouteService.TryAddRoute( new CustomRouteData("/Fred", typeof(Counter) ));
private void AddJonRoute()
=> customRouteService.TryAddRoute("/Jon", "SO76159043.Pages.FetchData");
private void Navigate()
=> navManager.NavigateTo("/Fred");
private void NavigateJon()
=> navManager.NavigateTo("/Jon");
}