HarmonyOS鸿蒙Next中使用@State + if/else + visibility实现多状态页面(加载中/成功/空数据/错误)的统一管理
HarmonyOS鸿蒙Next中使用@State + if/else + visibility实现多状态页面(加载中/成功/空数据/错误)的统一管理
我们应该发如何通过使用 [@State](/user/State) + if/else + visibility 来实现多状态页面(加载中 / 成功 / 空数据 / 错误)的统一管理呢?
使用场景
在很多业务场景下,我们都需要可能碰到比如商品页无商品、消息页无消息、文章加载失败等各种空或者异常的业务情况 ,但有时候我们开发会将状态各自设定,导致比较分散混乱。
实现思路
采用状态机的模式,我们用一个枚举 + 单一状态变量统一管理所有页面状态。
enum PageStatus {
Loading,
Success,
Empty,
Error
}
然后在页面中使用时,只依赖于单一的状态源。以此进行解耦
完整代码
enum PageStatus {
Loading,
Success,
Empty,
Error
}
@Entry
@Component
struct OrderListPage {
@State status: PageStatus = PageStatus.Loading;
@State orders: string[] = [];
@State errorMessage: string = '';
// 模拟加载订单数据
aboutToAppear() {
this.loadData();
}
private async loadData() {
this.status = PageStatus.Loading;
try {
// 模拟网络延迟
// await new Promise(resolve => setTimeout(resolve, 1500));
// 模拟不同结果(可注释某行测试不同状态)
// const mockData = ['订单 #20251201', '订单 #20251202']; // 正常数据
// const mockData: string[] = []; // 取消注释此行可测试“空数据”
throw new Error('服务器繁忙'); // 取消注释此行可测试“错误”
// if (mockData.length === 0) {
// this.status = PageStatus.Empty;
// } else {
// this.orders = mockData;
// this.status = PageStatus.Success;
// }
} catch (e) {
this.errorMessage = e.message || '加载失败,请重试';
this.status = PageStatus.Error;
}
}
build() {
Column({ space: 20 }) {
Text('我的订单')
.fontSize(22)
.fontWeight(FontWeight.Bold)
// 统一状态渲染
if (this.status === PageStatus.Loading) {
Column() {
Text('加载中...')
.fontColor('#999')
.fontSize(14)
}
.margin({ top: 100 })
} else if (this.status === PageStatus.Success) {
List({ space: 10 }) {
ForEach(
this.orders,
(order: string) => {
ListItem() {
Text(order)
.padding(15)
.width('100%')
.borderRadius(8)
.backgroundColor('#F8F9FA')
}
}
)
}
.width('100%')
.height('60%')
} else if (this.status === PageStatus.Empty) {
Column() {
Image($r('app.media.startIcon'))
.width(80)
.height(80)
.margin({ bottom: 15 })
.visibility(Visibility.Visible) // 图标占位(可选)
Text('暂无订单')
.fontColor('#999')
.fontSize(16)
Button('去逛逛')
.width(120)
.height(40)
.margin({ top: 15 })
.backgroundColor('#007DFF')
.onClick(() => {
// 跳转首页等
})
}
.margin({ top: 100 })
} else if (this.status === PageStatus.Error) {
Column() {
Image($r('app.media.startIcon'))
.width(80)
.height(80)
.margin({ bottom: 15 })
Text(this.errorMessage)
.fontColor(Color.Red)
.fontSize(16)
.textAlign(TextAlign.Center)
.width('80%')
Button('重试')
.width(120)
.height(40)
.margin({ top: 20 })
.backgroundColor('#007DFF')
.onClick(() => {
this.loadData(); // 重新加载
})
}
.margin({ top: 100 })
}
}
.padding(25)
.width('100%')
.height('100%')
}
}
function ProgressIndicator() {
throw new Error('Function not implemented.');
}
实现效果
通过统一的状态机来显示不 同状态下的场景。



更多关于HarmonyOS鸿蒙Next中使用@State + if/else + visibility实现多状态页面(加载中/成功/空数据/错误)的统一管理的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,使用[@State](/user/State)、条件渲染(if/else)和visibility来统一管理多状态页面是一种清晰且高效的做法。以下是实现方案:
1. 定义状态枚举
首先,使用枚举明确定义页面的几种状态:
enum PageState {
Loading, // 加载中
Success, // 成功(有数据)
Empty, // 空数据
Error // 错误
}
2. 使用@State管理状态
在组件中,使用[@State](/user/State)装饰器声明一个状态变量来跟踪当前页面状态:
[@State](/user/State) currentState: PageState = PageState.Loading
3. 条件渲染实现状态切换
在build()方法中,使用条件渲染(if/else)根据当前状态显示不同的UI:
build() {
Column() {
// 加载中状态
if (this.currentState === PageState.Loading) {
LoadingComponent()
}
// 成功状态(显示数据)
if (this.currentState === PageState.Success) {
DataContentComponent()
}
// 空数据状态
if (this.currentState === PageState.Empty) {
EmptyStateComponent()
}
// 错误状态
if (this.currentState === PageState.Error) {
ErrorComponent()
}
}
}
4. 使用visibility优化渲染
对于某些场景,可以使用visibility属性替代条件渲染,避免组件树频繁重建:
build() {
Column() {
// 使用visibility控制显示
LoadingComponent()
.visibility(this.currentState === PageState.Loading ? Visibility.Visible : Visibility.None)
DataContentComponent()
.visibility(this.currentState === PageState.Success ? Visibility.Visible : Visibility.None)
EmptyStateComponent()
.visibility(this.currentState === PageState.Empty ? Visibility.Visible : Visibility.None)
ErrorComponent()
.visibility(this.currentState === PageState.Error ? Visibility.Visible : Visibility.None)
}
}
5. 状态切换示例
在数据加载逻辑中更新状态:
async loadData() {
this.currentState = PageState.Loading
try {
const data = await api.fetchData()
if (data.length === 0) {
this.currentState = PageState.Empty
} else {
this.currentState = PageState.Success
// 更新数据
}
} catch (error) {
this.currentState = PageState.Error
}
}
选择建议
- 条件渲染(if/else):适合状态间UI差异大、组件结构不同的场景,不同状态组件完全独立
- visibility控制:适合状态间UI结构相似、仅内容变化的场景,避免组件重建开销
这种模式将状态管理集中化,使状态切换逻辑清晰,便于维护和扩展。

