空状态引导设计:Text + Button 组合与交互反馈

前言

空状态是应用中不可或缺的 UI 设计。当用户还没有任何数据时,空状态页面需要传达"这里没有内容"的信息,同时引导用户进行下一步操作。

"海风日记"在上首页、回顾页、标签管理页、搜索页等多个地方都设计了空状态引导,通过品牌元素(emoji 波浪)、提示文字和行动按钮的组合,引导用户创建第一篇日记。本文将从源码出发,深入讲解空状态的设计原则和实现方式。


一、空状态设计原则

1.1 空状态的三个要素

一个优秀的空状态应该包含以下三个要素:

要素 作用 示例
视觉元素 吸引注意力,缓解"空"的突兀感 🌊、📖、📊
提示文字 说明当前状态 "还没有日记哦"
行动按钮 引导用户下一步操作 "写第一篇日记"

1.2 海风日记的空状态场景

页面 视觉元素 提示文字 行动按钮
首页 🌊 "还没有日记哦" "写第一篇日记"
回顾页 📊 "还没有数据哦" "去写日记"
日历页 📖 "这个月还没有日记" 无(点击下方 +)
标签页 🏷️ "还没有标签" 输入框添加
搜索页 🌊 "没有找到相关内容" 无(换关键词)

二、首页空状态实现

2.1 源码

typescript 复制代码
if (this.diaryList.length === 0) {
  // 空状态:引导写第一篇日记
  Column({ space: 0 }) {
    // 视觉元素:波浪 emoji
    Text('🌊').fontSize(64).margin({ bottom: 20 })

    // 提示文字
    Text('还没有日记哦')
      .fontSize(18).fontColor(COLOR_TEXT_MAIN).fontWeight(FontWeight.Bold)
      .margin({ bottom: 8 })

    // 补充说明
    Text('记录今天的心情,让每一天都值得回忆')
      .fontSize(14).fontColor(COLOR_TEXT_HINT)
      .textAlign(TextAlign.Center)
      .padding({ left: 40, right: 40 })
      .margin({ bottom: 32 })

    // 行动按钮
    Button('写第一篇日记')
      .height(48).fontSize(16).fontColor('#FFFFFF').fontWeight(FontWeight.Bold)
      .backgroundColor(COLOR_PRIMARY).borderRadius(24)
      .padding({ left: 32, right: 32 })
      .shadow({ radius: 12, color: 'rgba(245,166,35,0.30)', offsetY: 4 })
      .onClick(() => {
        router.pushUrl({ url: 'pages/diary/WriteDiaryPage' })
      })
  }
  .width('100%').layoutWeight(1)
  .justifyContent(FlexAlign.Center)
  .alignItems(HorizontalAlign.Center)
}

2.2 布局分析

复制代码
┌──────────────────────────────┐
│                              │
│            🌊               │   ← 视觉元素(emoji)
│                              │
│     还没有日记哦              │   ← 主标题
│                              │
│ 记录今天的心情,让每一天      │
│ 都值得回忆                   │   ← 副标题
│                              │
│  ┌──────────────────────┐   │
│  │    写第一篇日记       │   │   ← 行动按钮
│  └──────────────────────┘   │
│                              │
└──────────────────────────────┘

三、回顾页空状态实现

3.1 源码

typescript 复制代码
if (MOCK_DIARIES.length === 0) {
  Column({ space: 12 }) {
    Text('📊').fontSize(48).margin({ top: 60 })
    Text('还没有数据哦')
      .fontSize(17).fontColor(COLOR_TEXT_MAIN).fontWeight(FontWeight.Bold)
    Text('写几篇日记后,这里会展示你的\n写作统计和情绪趋势')
      .fontSize(14).fontColor(COLOR_TEXT_HINT)
      .textAlign(TextAlign.Center).lineHeight(22)

    Button('去写日记')
      .height(44).fontSize(15).fontColor('#FFFFFF').fontWeight(FontWeight.Bold)
      .backgroundColor(COLOR_PRIMARY).borderRadius(22)
      .padding({ left: 28, right: 28 }).margin({ top: 24 })
      .onClick(() => router.pushUrl({ url: 'pages/diary/WriteDiaryPage' }))
  }
  .width('100%').alignItems(HorizontalAlign.Center).layoutWeight(1)
}

四、空状态的设计对比

4.1 不同场景的空状态

场景 emoji 标题 描述 按钮
首页空日记 🌊 "还没有日记哦" "记录今天的心情..." "写第一篇日记"
回顾空数据 📊 "还没有数据哦" "写几篇日记后..." "去写日记"
日历空月份 📖 "这个月还没有日记" "点击下方 + 记录..."
标签空列表 🏷️ "还没有标签" "添加标签可以帮你..." 输入框
搜索无结果 🌊 "没有找到相关内容" "换个关键词试试吧"

4.2 空状态与品牌一致性

所有空状态都遵循以下品牌规范:

  1. 使用 emoji 作为视觉元素:保持品牌调性一致
  2. 暖色系文字 :主标题使用 COLOR_TEXT_MAIN,副标题使用 COLOR_TEXT_HINT
  3. 橙色按钮 :CTA 按钮使用 COLOR_PRIMARY 品牌色
  4. 居中布局:所有空状态使用居中对齐

五、空状态的交互反馈

5.1 按钮点击反馈

typescript 复制代码
Button('写第一篇日记')
  .shadow({
    radius: 12,
    color: 'rgba(245,166,35,0.30)',  // 橙色阴影
    offsetY: 4
  })
  .onClick(() => {
    router.pushUrl({ url: 'pages/diary/WriteDiaryPage' })
  })

5.2 跳转后的行为

点击空状态按钮后,用户跳转到写日记页面,完成后返回首页,首页应该显示新的日记内容:

typescript 复制代码
// 在 onPageShow 中刷新数据
onPageShow() {
  this.diaryList = [...MOCK_DIARIES]
}

六、空状态与真实数据的过渡

6.1 条件渲染

typescript 复制代码
if (this.diaryList.length === 0) {
  // 空状态
  this.emptyState()
} else {
  // 数据列表
  this.diaryListContent()
}

6.2 过渡动画

typescript 复制代码
// 空状态到数据列表的过渡
Column()
  .transition({ type: TransitionType.Insert, opacity: 1 })
  .transition({ type: TransitionType.Delete, opacity: 0 })

七、常见问题与排查

7.1 空状态不显示

问题:数据为空时空状态没有显示。

原因:条件判断逻辑错误,或数据初始值不为空。

解决方案 :检查 @State 初始值和判断逻辑:

typescript 复制代码
@State diaryList: DiaryEntry[] = []  // 初始值为空数组

7.2 空状态和列表同时显示

问题:空状态和日记列表同时显示在页面上。

原因:条件渲染的 else 分支缺失。

解决方案:使用 if/else 确保互斥显示:

typescript 复制代码
if (data.length === 0) {
  // 空状态
} else {
  // 列表
}

总结

本文通过"海风日记"的多个空状态场景,深入讲解了空状态引导的设计和实现:

  1. 设计原则:视觉元素 + 提示文字 + 行动按钮
  2. 首页实现:emoji + 标题 + 描述 + 按钮的完整布局
  3. 多场景空状态:首页、回顾、日历、标签、搜索的差异化设计
  4. 品牌一致性:所有空状态遵循统一的品牌规范
  5. 交互反馈:按钮阴影、跳转后的数据刷新

下一篇文章将深入讲解 WaveHeaderBand 组件的品牌视觉头部封装,敬请期待。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

相关推荐
卷无止境21 小时前
当独立开发者也能造出3A画质的游戏:Godot引擎深度解析
后端·python·godot
独行侠影a1 天前
SpringBoot 分布式锁实战:Redisson 解决订单超卖并发问题
spring boot·分布式·后端
妙码生花1 天前
从 PHP 到 AI + Golang,程序员自救转型手记(五十八):后台系统配置管理实现
前端·后端·go
IT_陈寒1 天前
Java并行流把我坑惨了:原来不是线程安全的!
前端·人工智能·后端
Lihua奏1 天前
跨域:浏览器到底拦住了什么
后端
Lyra_Infra1 天前
Docker OCI Runtime 启动失败问题排查与解决
后端·docker·架构
XuCoder1 天前
Redis 哨兵模式:它到底是怎么保证高可用的
后端
敲个大西瓜1 天前
Springboot核心面试题
java·spring boot·后端
运维行者_1 天前
网络监控与ITSM集成:从告警到工单,实现运维自动化闭环
开发语言·网络·分布式·后端·架构·flask·php