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

.NET 8无预渲染场景下,如何在加载WASM组件时显示加载进度?

.NET 8 Blazor跨渲染模式页面切换的加载提示解决方案

针对从非WASM页面(如/home)切换到无预渲染的InteractiveWebAssemblyRenderMode页面(如/wasmPage)时,Blazor清空<main>后无加载提示的问题,以下是几个无需复杂修改的可行方案:

方案一:DOM突变观察器+CSS/JS(最简洁)

通过监听<main>元素的DOM变化,检测bl-load注释的出现/消失来控制加载提示的显示:

  1. 添加加载提示元素
    在主布局(如MainLayout.razor)中插入全局加载提示:
<div class="wasm-loader">
  <p>正在加载WASM内容...</p>
</div>
  1. 基础CSS样式
    设置提示的固定定位和默认隐藏状态:
.wasm-loader {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255,255,255,0.9);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  font-size: 1.2rem;
}
  1. DOM监听JS脚本
    在wwwroot/js/loader.js中添加突变观察器:
document.addEventListener('DOMContentLoaded', () => {
  const main = document.querySelector('main');
  const loader = document.querySelector('.wasm-loader');
  
  const observer = new MutationObserver(mutations => {
    // 检查main中是否存在bl-load注释
    const hasBlLoad = Array.from(main.childNodes).some(node => 
      node.nodeType === Node.COMMENT_NODE && node.textContent.includes('bl-load')
    );
    loader.style.display = hasBlLoad ? 'flex' : 'none';
  });
  
  // 监听main的子节点变化
  observer.observe(main, { childList: true });
});

最后在index.html中引入该脚本:

<script src="js/loader.js"></script>

方案二:导航事件+JS互操作

通过订阅导航事件,判断目标页面类型,主动控制加载提示:

  1. 布局中添加加载元素
    同方案一的加载提示元素。

  2. 订阅导航事件
    在MainLayout.razor中注入NavigationManager和IJSRuntime,并在初始化时订阅位置变化事件:

@inject NavigationManager NavManager
@inject IJSRuntime JSRuntime

<!-- 加载提示元素 -->
<div id="wasm-loader" class="wasm-loader">
  <p>正在加载WASM内容...</p>
</div>

@code {
  protected override void OnInitialized()
  {
    NavManager.LocationChanged += async (_, args) =>
    {
      // 根据路由判断是否为WASM页面(可根据实际路由规则调整)
      if (args.Location.Contains("/wasmPage"))
      {
        await JSRuntime.InvokeVoidAsync("showLoader");
        // 监听WASM加载完成事件
        await JSRuntime.InvokeVoidAsync("onWasmLoaded", () => HideLoader());
      }
    };
  }

  private async Task HideLoader()
  {
    await JSRuntime.InvokeVoidAsync("hideLoader");
  }
}
  1. 添加JS函数
    在wwwroot/js/interop.js中实现显示/隐藏逻辑:
function showLoader() {
  document.getElementById('wasm-loader').style.display = 'flex';
}

function hideLoader() {
  document.getElementById('wasm-loader').style.display = 'none';
}

function onWasmLoaded(callback) {
  // 监听Blazor WASM就绪事件
  if (window.Blazor?.webassemblyReady) {
    callback();
  } else {
    window.addEventListener('blazorWebAssemblyReady', callback);
  }
}

方案三:自定义RouteView拦截渲染

通过继承RouteView,在渲染WASM页面之前显示加载提示:

  1. 创建自定义RouteView
    新建CustomRouteView.razor:
@inherits RouteView
@inject IJSRuntime JSRuntime

@if (_showLoading)
{
  <div class="wasm-loader">
    <p>正在加载WASM内容...</p>
  </div>
}
else
{
  <LayoutView Layout="@Layout">
    <RouteData RouteData="@RouteData" />
  </LayoutView>
}

@code {
  private bool _showLoading;

  protected override async Task OnParametersSetAsync()
  {
    // 检查当前页面是否使用无预渲染的WASM渲染模式
    var renderAttr = RouteData.PageType.GetCustomAttributes(typeof(RenderModeAttribute), false)
      .Cast<RenderModeAttribute>()
      .FirstOrDefault();
    
    if (renderAttr?.RenderMode is InteractiveWebAssemblyRenderMode mode && !mode.Prerender)
    {
      _showLoading = true;
      // 等待WASM加载完成后更新状态
      await JSRuntime.InvokeVoidAsync("onWasmLoaded", () =>
      {
        _showLoading = false;
        StateHasChanged();
      });
    }
    else
    {
      _showLoading = false;
      await base.OnParametersSetAsync();
    }
  }
}
  1. 替换App.razor中的RouteView
    修改App.razor,使用自定义的CustomRouteView:
<Router AppAssembly="@typeof(App).Assembly">
  <Found Context="routeData">
    <CustomRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
  </Found>
  <NotFound>
    <LayoutView Layout="@typeof(MainLayout)">
      <p>抱歉,该页面不存在。</p>
    </LayoutView>
  </NotFound>
</Router>
  1. 引入JS函数
    同方案二中的onWasmLoaded等JS函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:32:53