Ionic中如何在http请求后移除ion-skeleton并处理空用户列表
原实现的核心问题
你现在的写法存在两个硬伤,导致根本没法区分“加载中”和“空列表”两个场景:
- 第一个是判断表达式有运算优先级bug:模板里写的
!users.length > 0,实际运行时会先执行!users.length(把空数组转成布尔值取反得到true),再把true转成数字1和0做比较,表达式的实际含义和你想的“长度大于0的时候不显示加载”完全不对等 - 第二个是状态粒度缺失:请求返回空数组的时候,
users.length依然是0,原判断条件依然成立,骨架屏会一直展示,根本没有触发空提示、真实列表渲染的分支逻辑
正确实现思路
把原来靠“数组长度”判断状态的逻辑,换成独立维护的加载状态标识,把场景拆成三个明确的分支,每个分支对应唯一的展示内容:
- 请求还在飞的时候:展示骨架屏
- 请求结束、且返回的用户数组长度大于0:展示真实的用户列表
- 请求结束、且返回的用户数组长度为0:展示“未找到用户”的提示
具体代码参考
- 组件类里新增加载状态变量,在请求完成时同步更新状态
// 组件内定义 isLoading = true; users: any[] = []; // 在ngOnInit或者对应触发请求的方法里调用 fetchUserList() { this.isLoading = true; this.userService.getUserList().subscribe({ next: (res) => { this.users = res; }, error: () => { this.users = []; }, complete: () => { // 不管请求成功还是失败,走到complete就代表请求结束 this.isLoading = false; } }) }
- 模板里替换原来的单条件判断,拆分三个展示块
<!-- 分支1:加载中,展示原有骨架屏 --> <div class="loading-users" *ngIf="isLoading"> <ion-list *ngFor="let item of [1, 2, 3, 4, 5, 6, 7]"> <ion-item> <ion-avatar slot="start"> <ion-skeleton-text animated></ion-skeleton-text> </ion-avatar> <ion-label> <div> <ion-skeleton-text animated style="width: 80%"></ion-skeleton-text> </div> <div style="margin-top:20px;"> <ion-skeleton-text animated style="width: 50%"></ion-skeleton-text> </div> </ion-label> </ion-item> </ion-list> </div> <!-- 分支2:加载完成且用户列表非空,展示真实数据 --> <ion-list *ngIf="!isLoading && users.length > 0"> <!-- 原有真实用户的渲染逻辑写在这里,比如循环渲染每个用户的头像、昵称 --> <ion-item *ngFor="let user of users"> <!-- 自定义真实内容结构 --> </ion-item> </ion-list> <!-- 分支3:加载完成但用户列表为空,展示提示 --> <div class="empty-user-tip" *ngIf="!isLoading && users.length === 0" style="padding: 2rem; text-align: center; color: #999;"> 未找到用户 </div>
小优化建议
- 不要硬编码骨架屏的循环数组长度,可以把需要展示的骨架条数抽成组件常量,后续调整数量只需要改常量值,不用翻模板改数组
- 空提示块可以根据你的页面风格加适配样式,不用完全照搬上面的内联样式
内容的提问来源于stack exchange,提问作者this.jind
相关产品推荐
相关产品推荐

