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

如何阻止Blazor页面重载并保留html标签的data-bs-theme属性

解决.NET 8 Blazor Web App中Bootstrap主题路由切换后丢失的问题

问题原因

当使用<NavLink>或<a>标签进行路由切换时,Blazor会重新生成DOM结构,根节点<html>的自定义属性(比如data-bs-theme)会被重置。而你原来的JS代码仅在页面刷新/首次加载时执行,路由切换时不会重新触发,导致主题属性丢失。

简单解决方案(适合新手)

步骤1:重构JS代码,封装成可调用的全局方法

把原来的自执行函数改成可复用的全局方法,同时保留页面加载时的初始化逻辑:

window.themeManager = {
    // 初始化主题
    applyTheme: function() {
        let theme = localStorage.getItem('theme');
        // 没有存储值时,跟随系统主题
        if (!theme) {
            theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
        }
        document.documentElement.setAttribute('data-bs-theme', theme);
    },
    // 切换主题的方法(保留切换功能)
    toggleTheme: function() {
        const currentTheme = document.documentElement.getAttribute('data-bs-theme');
        const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
        document.documentElement.setAttribute('data-bs-theme', newTheme);
        localStorage.setItem('theme', newTheme);
    }
};

// 页面首次加载时初始化主题
window.themeManager.applyTheme();

步骤2:在布局组件中监听渲染/导航事件,重新应用主题

因为所有页面都基于MainLayout渲染,我们可以在MainLayout.razor中,每次页面渲染完成后调用JS方法重新设置主题:

@inject IJSRuntime JSRuntime
@inject NavigationManager NavManager
@implements IDisposable

<!-- 你的布局内容 -->

@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        // 每次渲染完成都重新应用主题(包括路由切换后的渲染)
        await JSRuntime.InvokeVoidAsync("window.themeManager.applyTheme");
        await base.OnAfterRenderAsync(firstRender);
    }

    // 监听导航事件,确保路由切换后立即触发主题应用
    protected override void OnInitialized()
    {
        NavManager.LocationChanged += OnRouteChanged;
    }

    private async void OnRouteChanged(object? sender, LocationChangedEventArgs e)
    {
        await JSRuntime.InvokeVoidAsync("window.themeManager.applyTheme");
    }

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

方案生效逻辑

  • 路由切换时,Blazor会重新渲染MainLayout,OnAfterRenderAsync触发后调用JS重新设置data-bs-theme属性
  • 导航事件监听确保即使布局未重新渲染,路由切换后也会立即应用主题
  • 主题状态存在localStorage中,不会因为页面渲染丢失

额外说明

  • 如果你之前尝试OnAfterRenderAsync无效果,大概率是加了if(firstRender)判断,仅在首次渲染时执行,路由切换后不会触发
  • 无需移除InteractiveServer渲染模式,该方案兼容所有Blazor渲染模式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:08:10