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

Blazor 8中点击修改URL哈希的链接,如何触发NavigationManager.LocationChanged事件?

Blazor 8中触发哈希变化的LocationChanged事件解决方案

在Blazor 8 WebAssembly中,原生<a>标签修改URL哈希时不会触发NavigationManager.LocationChanged事件,这是因为Blazor 8默认的静态渲染模式下,原生链接不会经过Blazor的客户端路由系统。以下是几种可行的解决方法:

方法1:使用Blazor的NavigateTo替代原生链接

将原生<a>标签替换为Blazor的交互式导航,通过NavigationManager.NavigateTo方法修改哈希,这样会触发LocationChanged事件:

@page "/"
@rendermode InteractiveWebAssembly
@inject NavigationManager _navigationManager
@implements IDisposable

<h1>Hello, world!</h1>

<button @onclick="() => _navigationManager.NavigateTo("#login", forceLoad: false)">Login</button> |
<button @onclick="() => _navigationManager.NavigateTo("#signup", forceLoad: false)">Sign Up</button> |
<button @onclick="() => _navigationManager.NavigateTo("#forgotpassword", forceLoad: false)">Forgot Password</button>

@code {
    protected override void OnInitialized()
    {
        _navigationManager.LocationChanged += _navigationManager_LocationChanged;
        base.OnInitialized();
    }

    void _navigationManager_LocationChanged(object sender, LocationChangedEventArgs e)
    {
        Console.WriteLine("_navigationManager_LocationChanged: " + e.Location);
    }

    void IDisposable.Dispose()
    {
        _navigationManager.LocationChanged -= _navigationManager_LocationChanged;
    }
}

方法2:保留原生链接,监听浏览器hashchange事件

如果需要保留原生<a>标签,可以通过JS互操作监听浏览器的hashchange事件,再同步到Blazor中:

组件代码

@page "/"
@rendermode InteractiveWebAssembly
@inject NavigationManager _navigationManager
@inject IJSRuntime _jsRuntime
@implements IDisposable

<h1>Hello, world!</h1>

<a href="#login">Login</a> |
<a href="#signup"> Sign Up</a> |
<a href="#forgotpassword">Forgot Password</a>

@code {
    private DotNetObjectReference<Index>? _dotNetRef;

    protected override async Task OnInitializedAsync()
    {
        _navigationManager.LocationChanged += _navigationManager_LocationChanged;
        _dotNetRef = DotNetObjectReference.Create(this);
        await _jsRuntime.InvokeVoidAsync("setupHashChangeListener", _dotNetRef);
        await base.OnInitializedAsync();
    }

    [JSInvokable]
    public void OnHashChanged(string newUrl)
    {
        // 同步哈希变化到NavigationManager,触发LocationChanged
        _navigationManager.NavigateTo(newUrl, forceLoad: false, replace: true);
    }

    void _navigationManager_LocationChanged(object sender, LocationChangedEventArgs e)
    {
        Console.WriteLine("_navigationManager_LocationChanged: " + e.Location);
    }

    void IDisposable.Dispose()
    {
        _navigationManager.LocationChanged -= _navigationManager_LocationChanged;
        _dotNetRef?.Dispose();
        _jsRuntime.InvokeVoidAsync("removeHashChangeListener");
    }
}

新增JS代码(在wwwroot/index.html中)

<script>
    let hashChangeListener;
    function setupHashChangeListener(dotNetRef) {
        hashChangeListener = () => {
            dotNetRef.invokeMethodAsync('OnHashChanged', window.location.href);
        };
        window.addEventListener('hashchange', hashChangeListener);
    }
    function removeHashChangeListener() {
        if (hashChangeListener) {
            window.removeEventListener('hashchange', hashChangeListener);
        }
    }
</script>

关键注意事项

  • 确保组件使用交互式渲染模式:添加@rendermode InteractiveWebAssembly,静态渲染模式下不会处理客户端路由事件。
  • 使用NavigateTo时,forceLoad: false确保不会重载页面,仅修改客户端路由。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:47:11