如何在.NET Blazor Server应用中显示全局页面加载器?
Blazor Server 全局加载器实现方案
问题描述
在.NET Blazor WebAssembly应用中,我可以在index.html中添加如下加载器:
<body> <div id="app"> <!--Overlay Loader--> <div id="PageOverlay"> <div class="loader"> <div id="PageOverlaySvgBox" class="hat-logo"></div> <h1 data-bind="text:label" class="text-primary">جاري تحميل الصفحة...</h1> </div> </div> </div> <div id="blazor-error-ui"> An unhandled error has occurred. <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.webassembly.js"></script> <script>navigator.serviceWorker.register('service-worker.js');</script> </body>但Blazor Server应用中没有index.html,只有_Host.cshtml:
<body> <component type="typeof(App)" render-mode="ServerPrerendered" /> <div id="blazor-error-ui"> <environment include="Staging,Production"> An error has occurred. This application may no longer respond until reloaded. </environment> <environment include="Development"> An unhandled exception has occurred. See browser dev tools for details. </environment> <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.server.js"></script> </body>请问我应在哪里添加加载器?或者,如何在任意页面加载时显示全局加载器?
一、添加应用启动时的初始加载器
Blazor Server里的_Host.cshtml就对应WASM的index.html,直接把加载器代码放在<component>标签的上方即可:
<body> <!-- 全局加载器 --> <div id="PageOverlay"> <div class="loader"> <div id="PageOverlaySvgBox" class="hat-logo"></div> <h1 class="text-primary">جاري تحميل الصفحة...</h1> </div> </div> <component type="typeof(App)" render-mode="ServerPrerendered" /> <div id="blazor-error-ui"> <environment include="Staging,Production"> An error has occurred. This application may no longer respond until reloaded. </environment> <environment include="Development"> An unhandled exception has occurred. See browser dev tools for details. </environment> <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.server.js"></script> <!-- Blazor连接完成后隐藏加载器 --> <script> document.addEventListener('blazor.server.connectionEstablished', () => { document.getElementById('PageOverlay').style.display = 'none'; }); </script> </body>
再给加载器加个全局CSS(放到wwwroot/css/site.css里),确保它默认覆盖整个页面:
#PageOverlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255,255,255,0.9); display: flex; justify-content: center; align-items: center; z-index: 9999; } .loader { text-align: center; }
二、实现页面切换时的全局加载器
如果要在路由跳转(页面加载)时自动显示加载器,按以下步骤来:
- 创建全局加载器组件
在Shared文件夹下新建GlobalLoader.razor:
@if (IsLoading) { <div id="PageOverlay"> <div class="loader"> <div id="PageOverlaySvgBox" class="hat-logo"></div> <h1 class="text-primary">جاري تحميل الصفحة...</h1> </div> </div> } @code { [Parameter] public bool IsLoading { get; set; } }
- 在App.razor中集成控制逻辑
修改App.razor,通过NavigationManager监听路由变化,控制加载器的显示/隐藏:
<CascadingValue Value="this"> <GlobalLoader IsLoading="@_isLoading" /> <Router AppAssembly="@typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> <FocusOnNavigate RouteData="@routeData" Selector="h1" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <LayoutView Layout="@typeof(MainLayout)"> <p role="alert">Sorry, there's nothing at this address.</p> </LayoutView> </NotFound> </Router> </CascadingValue> @code { [Inject] private NavigationManager NavigationManager { get; set; } private bool _isLoading; protected override void OnInitialized() { // 路由开始跳转时显示加载器 NavigationManager.LocationChanging += (_, __) => { _isLoading = true; StateHasChanged(); }; // 路由跳转完成后隐藏加载器 NavigationManager.LocationChanged += (_, __) => { _isLoading = false; StateHasChanged(); }; } }
- 复用之前的CSS样式
把第一步里的加载器CSS保留,确保样式生效。
内容的提问来源于stack exchange,提问作者Ibrahim Hamaty
相关产品推荐
相关产品推荐

