前面用iframe實現了多標簽頁,這次是不用iframe實現的多標簽頁.參考了一下Ant Design Blazor.
基本功能已經都實現了不論是標簽滾動、激活、左移、右移、關閉其他,還是在內容頁跳轉、新增、關閉標簽都有實現。
已經可以用來做實際項目
源碼地址: https://github.com/liningit/BlazorWebassemblyMultiPagesTabNoIframe
實現原理是新建一個類繼承RouteView,在此類里面的Render方法中可以通過RouteData獲取當前路由對應的對象.然后生成RenderFragment.
然后將其保存到List中,然后循環顯示出來.對於未激活的通過display:none隱藏就可以了,這樣哪怕切換標簽狀態也是保存的並不會刷新
public class ReuseTabsRouteView : RouteView
{
[Inject]
public TabSetTool TabSetTool { get; set; }
[Inject]
public NavigationManager Navmgr { get; set; }
protected override void Render(RenderTreeBuilder builder)
{
var layoutType = RouteData.PageType.GetCustomAttribute<LayoutAttribute>()?.LayoutType ?? DefaultLayout;
var body = CreateBody(RouteData, Navmgr.Uri);
builder.OpenComponent<CascadingValue<ReuseTabsRouteView>>(0);
builder.AddAttribute(1, "Name", "RouteView");
builder.AddAttribute(2, "Value", this);
builder.AddAttribute(3, "ChildContent", (RenderFragment)(b =>
{
b.OpenComponent(20, layoutType);
b.AddAttribute(21, "Body", body);
b.CloseComponent();
}));
builder.CloseComponent();
var url = "/" + Navmgr.ToBaseRelativePath(Navmgr.Uri);
if (url != "/#")
{
var selTab = TabSetTool.Pages.FirstOrDefault(m => m.Url == url && (m.Title == TabSetTool.Title || string.IsNullOrEmpty(m.Title)));
if (selTab == null)
{
TabSetTool.Pages.Add(new Tab
{
Body = body,
Url = url,
Title = TabSetTool.Title,
IsActive = true,
});
}
else
{
selTab.Title = TabSetTool.Title;
selTab.Body = body;
selTab.IsActive = true;
}
}
}
private RenderFragment CreateBody(RouteData routeData, string url)
{
return builder =>
{
builder.OpenComponent(0, routeData.PageType);
foreach (var routeValue in routeData.RouteValues)
{
builder.AddAttribute(1, routeValue.Key, routeValue.Value);
}
builder.CloseComponent();
};
}
}
App.razor中將RouteView改成ReuseTabsRouteView.
另外要注意TabSet中一定要有
[CascadingParameter(Name = "RouteView")]
public ReuseTabsRouteView RouteView { get; set; }
這兩句,要不然頁面會不更新