✅ 背景说明
在企业级应用中,列表、图表、卡片等组件经常会处于“无数据”状态,比如:
-
搜索结果为空;
-
网络请求失败;
-
初始状态未配置内容;
如果每次都手动编写空视图 UI,不仅重复,而且风格不统一、逻辑容易分散。因此封装一个灵活、统一风格的 EmptyView
空状态组件,具有重要意义。
🧱 一、组件功能目标
-
支持空状态类型(如“无数据”“加载失败”);
-
支持图标/插图展示;
-
支持文字说明;
-
可配置按钮操作(如“重试”);
-
支持插槽自定义内容。
📦 二、组件结构定义
@Component
struct EmptyView {
@Prop type: 'empty' | 'error' | 'search' = 'empty';
@Prop message: string = '暂无数据';
@Prop icon: string = '';
@Prop actionText: string = '';
@Prop onAction: () => void = () => {};
@Slot content?: () => void;
}
🖼️ 三、图标默认映射
private iconMap: Record<string, string> = {
empty: '/resources/empty.svg',
error: '/resources/error.svg',
search: '/resources/search.svg'
};
private getIcon(): string {
return this.icon || this.iconMap[this.type] || this.iconMap['empty'];
}
🧩 四、组件 UI 实现
build() {
Column()
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
.padding(20) {
Image(this.getIcon())
.width(100)
.height(100)
.margin({ bottom: 10 })
if (this.content) {
this.content!()
} else {
Text(this.message).fontSize(14).color('#888')
}
if (this.actionText) {
Button(this.actionText)
.margin({ top: 10 })
.onClick(() => this.onAction())
}
}
}
🧪 五、父组件使用示例
✅ 默认样式使用
EmptyView({
type: 'empty',
message: '您还没有添加任何记录',
actionText: '去创建',
onAction: () => router.pushUrl({ url: 'createPage' })
})
🎨 插槽自定义内容
EmptyView({
icon: '/resources/custom.svg',
actionText: '重试',
onAction: () => this.reload()
}) {
Text('网络加载失败,请稍后重试').fontSize(15).color('#f44336')
}
⚠️ 六、易错点与规范建议
问题 | 原因 | 建议 |
---|---|---|
icon 无法显示 | 路径未正确配置或缺少资源文件 | 使用资源目录下的标准路径,如 /resources/*.svg |
插槽未渲染 | 未判断 if (this.content) | 插槽渲染需判断并调用 this.content!() |
样式不统一 | 每页自定义文案和颜色 | 建议约定统一字号、颜色、图标大小,维护品牌统一性 |
🚀 七、拓展建议
-
支持多种图标风格切换(outline、filled);
-
结合网络状态自动判断
error
与empty
; -
添加“自动消失动画”用于加载完成场景;
-
提供
mode="full/inline"
适配全页或局部组件; -
统一导出
EmptyView
+EmptyStateEnum
枚举 + 配套资源;
✅ 小结
本篇构建了一个支持图标、说明、插槽与操作按钮的企业级 EmptyView
组件。它帮助企业项目实现“零状态体验标准化”,减少重复工作,提升产品一致性。