Ionic 加载动画(Loading)在 2025 年最常用、最好看的几种写法,直接给你最新 + 最丝滑的完整方案(支持 Angular / React / Vue / 任意页面全局使用)
1. 官方最新 ion-loading(2025 年推荐首选)
最简单全局调用(一句话搞定)
import { LoadingController } from '@ionic/angular'; // Angular
// React 用 useIonLoading()
// Vue 用 useIonLoading()
async showLoading() {
const loading = await this.loadingController.create({
message: '请稍候...', // 可留空,更清爽
spinner: 'crescent', // 2025 年最受欢迎的动画
duration: 0, // 0 = 不自动关闭,手动 dismiss
translucent: true,
backdropDismiss: false, // 点击背景不关闭
cssClass: 'my-custom-loading' // 自定义样式用
});
await loading.present();
// 用完一定要 dismiss!
// await loading.dismiss();
}
2025 年最流行的 8 种 spinner(直接复制名字用)
| spinner 值 | 效果描述 | 推荐场景 |
|---|---|---|
"crescent" | 半月旋转(最美最现代) | 2025 年最推荐! |
"circles" | 8个小圆点跳动 | 经典好看 |
"dots" | 三个点呼吸动画 | 简洁优雅 |
"lines" | 垂直线条伸缩 | 轻量级 |
"bubbles" | 气泡上升 | 可爱风格 |
"circular" | 环形旋转(iOS 原生风) | iOS 项目 |
"ios" | 老版 iOS 菊花 | 兼容老设备 |
null 或不写 | 完全自定义 HTML | 想放 Lottie 动画时用 |
2. 全局统一美化(global.scss 推荐放这里)
/* 全局美化 loading(所有页面自动生效) */
.my-custom-loading {
--background: rgba(0, 0, 0, 0.7); // 半透明黑底
--spinner-color: #ffffff; // 白色动画
/* 圆角 + 居中文字更清晰 */
.loading-wrapper {
background: rgba(20, 20, 40, 0.95);
border-radius: 16px;
padding: 24px 32px;
box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}
/* 文字白色 + 更大更清晰 */
.loading-content {
color: white;
font-size: 16px;
font-weight: 500;
}
}
/* 超小号极简 loading(常用于按钮内) */
.mini-loading {
--background: transparent;
--spinner-color: var(--ion-color-primary);
.loading-wrapper {
background: none;
padding: 0;
}
}
3. 完整实战例子(最常用 4 种场景)
场景1:网络请求时自动显示(推荐封装)
// service 或 utils 中封装
async presentLoading(message = '加载中...') {
await this.loadingController.dismiss(); // 先关掉旧的
const loading = await this.loadingController.create({
message,
spinner: 'crescent',
cssClass: 'my-custom-loading'
});
await loading.present();
return loading; // 返回出去,请求完成后 dismiss
}
// 使用:
const loading = await this.presentLoading();
try {
await this.api.getData();
} finally {
await loading.dismiss(); // 无论成功失败都关掉
}
场景2:带成功/失败提示的 loading(超实用)
const loading = await this.loadingController.create({
spinner: 'crescent',
message: '提交中...'
});
await loading.present();
try {
await this.submit();
loading.message = '<ion-icon name="checkmark-circle" color="success"></ion-icon> 提交成功';
loading.spinner = null;
setTimeout(() => loading.dismiss(), 1500);
} catch {
loading.message = '<ion-icon name="close-circle" color="danger"></ion-icon> 提交失败';
loading.spinner = null;
setTimeout(() => loading.dismiss(), 2000);
}
场景3:使用 Lottie 动画(2025 年高端方案)
const loading = await this.loadingController.create({
spinner: null,
message: `
<div style="text-align:center; padding:20px;">
<dotlottie-player
src="https://assets5.lottiefiles.com/packages/lf20_szdrj7qh.json"
background="transparent"
speed="1"
style="width:80px;height:80px;margin:0 auto"
loop autoplay>
</dotlottie-player>
<div style="margin-top:16px;color:#fff;">加载中...</div>
</div>
`,
cssClass: 'lottie-loading'
});
await loading.present();
(记得先 npm install @lottiefiles/dotlottie-web)
场景4:React 写法(useIonLoading 超简洁)
const [present, dismiss] = useIonLoading();
await present({
message: '保存中...',
spinner: 'crescent',
duration: 0
});
// 完成后
dismiss();
推荐 2025 年最优雅的默认配置(放全局一次就行)
// 在 app.component.ts 里拦截所有 http,自动 loading
this.httpRequestInterceptor = this.httpClient.intercept({
// 每次请求自动 present
// 响应结束自动 dismiss
});
或者直接用我的这个全局服务,所有页面一句话调用:
await this.loader.show('请稍候...');
// ...你的代码
await this.loader.hide();
需要我发你这个全局 loader 服务的完整代码吗?30 行搞定全项目所有 loading,再也不用每次手动 create/dismiss 了!
想要骨架屏(Skeleton)+ loading 组合、页面切换转场动画,也随时说,我直接给你模板!