You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor组件间属性控制:NavMenu切换MainLayout按钮可见性

解决方案

针对你的需求,这里提供两种可行的实现方式,适配你提到的状态管理或直接路由监听场景:

方法一:直接监听路由变化(最简方案)

不需要额外状态管理,通过Blazor内置的NavigationManager监听路由切换,直接控制按钮显示状态:

步骤与代码示例

  1. 在MainLayout.razor中注入NavigationManager,并实现IDisposable用于清理事件订阅
  2. 修正isMenuBtnHidden的默认值(注意:hidden属性为true时元素隐藏,所以默认隐藏按钮需设为true)
  3. 监听路由变化,判断当前是否为/home页面,动态更新按钮状态
@inject NavigationManager NavManager
@implements IDisposable

<div class="sidebar" hidden="@(!state.isAutenticate)" >
    <NavMenu />
</div>
<main>
    <div class="top-row px-4" style="text-align:center;display:inherit !important; ">
        <h1><b></b></h1>
        <table>
            <tr>
                @if (state.UserObj != null )
                {
                    <td>Hello: </td>
                    <td> @(state.UserObj.FirstName  + " " +  state.UserObj.LastName) </td>
                }
            </tr>
        </table>
    </div>

    <!-- 修改按钮点击事件为返回首页 -->
    <button hidden="@isMenuBtnHidden" @onclick="NavigateToHome"> 返回首页 </button>
</main>

@code {
    // 默认隐藏按钮(对应初始在/home页面)
    private bool isMenuBtnHidden = true;

    protected override void OnInitialized()
    {
        // 初始化时判断当前路由状态
        UpdateButtonVisibility(NavManager.Uri);
        // 订阅路由变化事件
        NavManager.LocationChanged += OnRouteChanged;
    }

    // 路由变化时更新按钮状态
    private void OnRouteChanged(object? sender, LocationChangedEventArgs e)
    {
        UpdateButtonVisibility(e.Location);
        StateHasChanged();
    }

    // 判断当前是否为/home页面,控制按钮显示
    private void UpdateButtonVisibility(string currentUri)
    {
        var relativePath = NavManager.ToBaseRelativePath(currentUri);
        // 非/home页面时显示按钮(isMenuBtnHidden设为false)
        isMenuBtnHidden = relativePath.Equals("home", StringComparison.OrdinalIgnoreCase);
    }

    // 返回首页逻辑
    private void NavigateToHome()
    {
        NavManager.NavigateTo("/home");
    }

    // 组件销毁时取消订阅,避免内存泄漏
    public void Dispose()
    {
        NavManager.LocationChanged -= OnRouteChanged;
    }
}

方法二:使用状态容器(符合状态管理器需求)

如果需要在多个组件间共享路由状态,或后续有更复杂的状态交互需求,可以用状态容器实现:

1. 创建状态容器类

public class RouteState
{
    private string _currentPath = string.Empty;

    public string CurrentPath
    {
        get => _currentPath;
        set
        {
            if (_currentPath != value)
            {
                _currentPath = value;
                // 状态变化时通知订阅者
                OnStateChanged?.Invoke();
            }
        }
    }

    // 状态变化事件
    public event Action? OnStateChanged;
}

2. 注册状态容器(Program.cs)

// 注册为单例,确保全局共享状态
builder.Services.AddSingleton<RouteState>();

3. 更新MainLayout.razor

@inject RouteState RouteState
@inject NavigationManager NavManager
@implements IDisposable

<div class="sidebar" hidden="@(!state.isAutenticate)" >
    <NavMenu />
</div>
<main>
    <div class="top-row px-4" style="text-align:center;display:inherit !important; ">
        <h1><b></b></h1>
        <table>
            <tr>
                @if (state.UserObj != null )
                {
                    <td>Hello: </td>
                    <td> @(state.UserObj.FirstName  + " " +  state.UserObj.LastName) </td>
                }
            </tr>
        </table>
    </div>

    <button hidden="@isMenuBtnHidden" @onclick="NavigateToHome"> 返回首页 </button>
</main>

@code {
    private bool isMenuBtnHidden = true;

    protected override void OnInitialized()
    {
        // 初始化当前路由状态
        RouteState.CurrentPath = NavManager.ToBaseRelativePath(NavManager.Uri);
        UpdateButtonVisibility();
        // 订阅状态变化事件
        RouteState.OnStateChanged += OnRouteStateUpdated;
        // 监听路由变化,同步更新状态容器
        NavManager.LocationChanged += OnRouteChanged;
    }

    private void OnRouteChanged(object? sender, LocationChangedEventArgs e)
    {
        RouteState.CurrentPath = NavManager.ToBaseRelativePath(e.Location);
    }

    private void OnRouteStateUpdated()
    {
        UpdateButtonVisibility();
        StateHasChanged();
    }

    private void UpdateButtonVisibility()
    {
        isMenuBtnHidden = RouteState.CurrentPath.Equals("home", StringComparison.OrdinalIgnoreCase);
    }

    private void NavigateToHome()
    {
        NavManager.NavigateTo("/home");
    }

    public void Dispose()
    {
        RouteState.OnStateChanged -= OnRouteStateUpdated;
        NavManager.LocationChanged -= OnRouteChanged;
    }
}

内容的提问来源于stack exchange,提问作者gal mor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 11:50:19