MudBlazor中点击MudNavLink无法更新AppBar文本,求解决方案
问题分析
绑定OnClick事件后未生效的核心原因有两个:
- 若使用Blazor服务器端渲染,导航操作可能导致
MainLayout组件重新初始化,重置appBarText的初始值 MudNavLink的导航优先级高于OnClick事件的状态更新,导致状态更新被后续组件重置覆盖
以下提供两种可靠的解决方式:
方式一:用状态容器持久化标题状态(适用于服务器端Blazor)
服务器端Blazor中组件状态会在导航后重置,需通过共享状态容器保存标题:
- 创建状态服务类:
public class AppStateService { private string _appBarText = "Default AppBar Text"; public string AppBarText { get => _appBarText; set { _appBarText = value; OnAppBarTextChanged?.Invoke(); } } public event Action? OnAppBarTextChanged; }
- 在
Program.cs中注册服务:
builder.Services.AddScoped<AppStateService>();
- 修改
MainLayout.razor,注入服务并监听状态变化:
@inject AppStateService AppState @implements IDisposable <MudThemeProvider /> <MudPopoverProvider /> <MudDialogProvider /> <MudSnackbarProvider /> <MudLayout> <MudAppBar Color="Color.Primary" Fixed="true"> <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="DrawerToggle" /> @AppState.AppBarText </MudAppBar> <MudDrawer @bind-Open="@_drawerOpen" Anchor="Anchor.Left"> <MudDrawerContainer> <MudNavMenu Bordered="true"> <MudNavLink Href="" Match="NavLinkMatch.All" OnClick="@(() => AppState.AppBarText = "Home")">Home</MudNavLink> <MudNavLink Href="/counter" OnClick="@(() => AppState.AppBarText = "Counter")">Counter</MudNavLink> <MudNavLink Href="/fetchdata" OnClick="@(() => AppState.AppBarText = "FetchData")">FetchData</MudNavLink> </MudNavMenu> </MudDrawerContainer> </MudDrawer> <MudMainContent> <MudContainer MaxWidth="MaxWidth.ExtraLarge"> @Body </MudContainer> </MudMainContent> </MudLayout> @code { bool _drawerOpen = true; protected override void OnInitialized() { AppState.OnAppBarTextChanged += StateHasChanged; } private void DrawerToggle() { _drawerOpen = !_drawerOpen; } public void Dispose() { AppState.OnAppBarTextChanged -= StateHasChanged; } }
方式二:监听路由自动更新标题(推荐,适用于所有Blazor类型)
无需依赖点击事件,通过监听路由变化自动匹配标题,覆盖所有导航场景:
修改MainLayout.razor,注入NavigationManager并监听路由变化:
@inject NavigationManager NavManager @implements IDisposable <MudThemeProvider /> <MudPopoverProvider /> <MudDialogProvider /> <MudSnackbarProvider /> <MudLayout> <MudAppBar Color="Color.Primary" Fixed="true"> <MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="DrawerToggle" /> @CurrentPageTitle </MudAppBar> <MudDrawer @bind-Open="@_drawerOpen" Anchor="Anchor.Left"> <MudDrawerContainer> <MudNavMenu Bordered="true"> <MudNavLink Href="" Match="NavLinkMatch.All">Home</MudNavLink> <MudNavLink Href="/counter">Counter</MudNavLink> <MudNavLink Href="/fetchdata">FetchData</MudNavLink> </MudNavMenu> </MudDrawerContainer> </MudDrawer> <MudMainContent> <MudContainer MaxWidth="MaxWidth.ExtraLarge"> @Body </MudContainer> </MudMainContent> </MudLayout> @code { bool _drawerOpen = true; private string CurrentPageTitle = "Default AppBar Text"; protected override void OnInitialized() { UpdateTitleFromRoute(NavManager.Uri); NavManager.LocationChanged += OnLocationChanged; } private void OnLocationChanged(object? sender, LocationChangedEventArgs e) { UpdateTitleFromRoute(e.Location); StateHasChanged(); } private void UpdateTitleFromRoute(string uri) { var path = NavManager.ToBaseRelativePath(uri); CurrentPageTitle = path switch { "" => "Home", "counter" => "Counter", "fetchdata" => "FetchData", _ => "Default AppBar Text" }; } private void DrawerToggle() { _drawerOpen = !_drawerOpen; } public void Dispose() { NavManager.LocationChanged -= OnLocationChanged; } }
原有代码失效原因
若使用WebAssembly Blazor,原有代码理论上应生效,但可能受调试缓存或MudNavLink导航行为干扰。上述两种方式均可彻底解决问题,其中方式二更推荐,能覆盖直接输入URL、浏览器前进后退等所有导航场景。
内容的提问来源于stack exchange,提问作者ndn
相关产品推荐
相关产品推荐

