如何在MAUI Blazor中抽象封装加载指示器(Spinner)
Blazor 统一实现加载指示器的优雅方案
不用每个页面都写重复的加载逻辑,通过自定义基类+通用Spinner组件就能搞定,步骤如下:
1. 构建带加载状态的基类
创建一个继承自ComponentBase的基类,统一管理加载状态和异步操作的包裹逻辑,所有需要加载状态的页面/组件都继承这个基类:
public class LoadingComponentBase : ComponentBase { protected bool IsLoading { get; private set; } protected async Task ExecuteWithLoading(Func<Task> action) { IsLoading = true; StateHasChanged(); // 强制触发UI更新,立刻显示加载状态 try { await action(); } finally { IsLoading = false; StateHasChanged(); } } }
这个基类里的ExecuteWithLoading方法会自动帮你处理加载状态的切换,不用手动写IsLoading = true/false。
2. 实现通用Spinner组件
写一个可复用的Spinner.razor组件,负责渲染加载动画和提示文本:
@if (IsVisible) { <div class="spinner-overlay"> <div class="spinner"></div> @if (!string.IsNullOrEmpty(Message)) { <p class="spinner-message">@Message</p> } </div> } @code { [Parameter] public bool IsVisible { get; set; } [Parameter] public string Message { get; set; } = "加载中..."; }
再给组件加基础样式(可以放到全局CSS文件里):
.spinner-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255,255,255,0.9); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 9999; } .spinner { border: 4px solid #e0e0e0; border-top-color: #2196f3; border-radius: 50%; width: 50px; height: 50px; animation: spin 1s linear infinite; } .spinner-message { margin-top: 16px; color: #666; font-size: 14px; } @keyframes spin { to { transform: rotate(360deg); } }
3. 在页面/组件中使用
让你的页面或组件继承LoadingComponentBase,然后用ExecuteWithLoading包裹异步数据加载逻辑,最后根据IsLoading控制Spinner的显示:
@page "/user-list" @inherits LoadingComponentBase <Spinner IsVisible="@IsLoading" Message="正在加载用户列表..." /> @if (UserList != null) { <div class="user-list"> @foreach (var user in UserList) { <div class="user-item">@user.Name</div> } </div> } @code { private List<User> UserList { get; set; } protected override async Task OnInitializeAsync() { await ExecuteWithLoading(async () => { // 实际项目里替换成真实的数据请求 await Task.Delay(1500); UserList = await UserService.GetAllUsersAsync(); }); } }
额外优化点
- 如果需要处理加载失败的情况,可以在基类里增加
IsError和ErrorMessage属性,在ExecuteWithLoading的catch块中设置状态,然后在页面里渲染错误提示。 - 要是只想给组件局部加加载(不是全屏),可以修改Spinner的CSS,把
position: fixed改成position: relative,并调整父容器的样式。 - 可以给基类增加重载方法,支持带返回值的异步操作,比如
ExecuteWithLoading<T>(Func<Task<T>> action),方便获取异步操作的返回结果。
内容的提问来源于stack exchange,提问作者Luka
相关产品推荐
相关产品推荐

