2026-08-10-mobile-h5-empty-state.md 6.3 KB

mobile-h5 全局空态(方案 B)Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: 将 van-empty 统一为方案 B(薄荷绿虚线软卡 + 圆形 inbox 插画 + 主/副文案),全站空态一致。

Architecture: 只改 H5 shim 组件 mobile-h5/components/van-empty/van-empty.vue;页面经 easycom / 显式 import 自动吃到新样式。主页补可选 tip;demo comps 演示副文案。

Tech Stack: uni-app Vue(Options API)、scoped CSS、三墙 Token(#0a9f6d 等)

Spec: docs/superpowers/specs/2026-08-10-mobile-h5-empty-state-design.md
视觉参考: mobile-ui/zkxw-mobile-empty-state-demo.html 方案 B


File map

路径 职责
mobile-h5/components/van-empty/van-empty.vue 方案 B 结构 + 样式 + tip prop
mobile-h5/pages/index/index.vue 空菜单空态补 tip
mobile-h5/pages/demo/comps.vue 演示页补 tip(可选副文案)
mobile-h5/pages/demo/list.vue 保持 description="暂无数据",无 tip(验证无占位)

Task 1: 重写 van-empty 为方案 B

Files:

  • Modify: mobile-h5/components/van-empty/van-empty.vue

  • [x] Step 1: 替换组件全文

将文件替换为:

<template>
  <view class="v-empty">
    <view class="v-empty__card">
      <view class="v-empty__blob">
        <view class="v-empty__inbox">
          <view class="v-empty__inbox-lid" />
          <view class="v-empty__inbox-body" />
        </view>
      </view>
      <text class="v-empty__desc">{{ description || '暂无数据' }}</text>
      <text v-if="tip" class="v-empty__tip">{{ tip }}</text>
    </view>
  </view>
</template>

<script>
  /** H5 兼容:替代 @vant/weapp van-empty(方案 B 虚线软卡) */
  export default {
    name: 'VanEmptyShim',
    props: {
      description: { type: String, default: '' },
      tip: { type: String, default: '' }
    }
  }
</script>

<style scoped>
  .v-empty {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 16rpx 0;
  }

  .v-empty__card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16rpx;
    padding: 44rpx 28rpx 40rpx;
    border-radius: 28rpx;
    background: linear-gradient(165deg, #eef9f3 0%, #ffffff 55%);
    border: 3rpx dashed #b7e5d0;
    box-shadow: inset 0 0 0 1rpx rgba(255, 255, 255, 0.8);
  }

  .v-empty__blob {
    width: 128rpx;
    height: 128rpx;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #ffffff, #d8f3e7 70%);
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /* CSS 近似 inbox 图标,避免小程序/H5 对 inline SVG 兼容差异 */
  .v-empty__inbox {
    position: relative;
    width: 56rpx;
    height: 48rpx;
  }

  .v-empty__inbox-lid {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 18rpx;
    border: 4rpx solid #0a9f6d;
    border-bottom: none;
    border-radius: 8rpx 8rpx 0 0;
    box-sizing: border-box;
  }

  .v-empty__inbox-body {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 34rpx;
    border: 4rpx solid #0a9f6d;
    border-radius: 0 0 8rpx 8rpx;
    box-sizing: border-box;
  }

  .v-empty__inbox-body::before {
    content: '';
    position: absolute;
    left: 10rpx;
    right: 10rpx;
    top: -10rpx;
    height: 16rpx;
    border: 4rpx solid #0a9f6d;
    border-top: none;
    border-radius: 0 0 6rpx 6rpx;
    box-sizing: border-box;
    background: transparent;
  }

  .v-empty__desc {
    font-size: 26rpx;
    color: #5d746a;
    text-align: center;
    line-height: 1.4;
  }

  .v-empty__tip {
    font-size: 22rpx;
    color: #8aa198;
    text-align: center;
    line-height: 1.4;
  }
</style>

说明:用 CSS 拼 inbox 轮廓,避免 uni-app H5 对 <svg><use> 不稳定;视觉对齐 Demo B 的绿色线框收件箱。

  • Step 2: 自检色值

确认文件中无 #10b981;主色仅为 #0a9f6d。

  • Step 3: Commit(已并入 ef259f1f)

Task 2: 调用方补 tip(主页 + comps)

Files:

  • Modify: mobile-h5/pages/index/index.vue
  • Modify: mobile-h5/pages/demo/comps.vue
  • Verify only: mobile-h5/pages/demo/list.vue(不改,保持无 tip)

  • [x] Step 1: 主页空态加 tip

在 mobile-h5/pages/index/index.vue 将:

<VanEmpty v-else description="暂无可用菜单权限" />

改为:

<VanEmpty
  v-else
  description="暂无可用菜单权限"
  tip="请联系管理员开通功能入口"
/>
  • Step 2: comps 演示页加 tip

在 mobile-h5/pages/demo/comps.vue 将:

<van-empty description="暂无相关数据" />

改为:

<van-empty
  description="暂无相关数据"
  tip="可下拉刷新,或点击上方按钮新增一条记录"
/>
  • Step 3: 确认 list 页不传 tip

mobile-h5/pages/demo/list.vue 保持:

<van-empty v-if="!list.length" description="暂无数据" />

验收:无 tip 时不出现空白副文案行。

  • Step 4: Commit(已并入 ef259f1f)

Task 3: 视觉验收

Files: 无代码变更

  • Step 1: 本地打开 / 刷新 H5(请本地刷新确认)

主页(菜单为空)应看到:虚线软卡、圆形插画、主文案「暂无可用菜单权限」、副文案「请联系管理员开通功能入口」;无 ∅。

  • Step 2: 对照 Demo

对照 mobile-ui/zkxw-mobile-empty-state-demo.html 方案 B:结构与色调一致即可(inbox 为 CSS 近似)。

  • [x] Step 3: 抽查 list / comps

  • comps:有 tip

  • list 清空数据后:仅主文案「暂无数据」,无 tip 占位


Spec coverage checklist

Spec 要求 Task
方案 B 视觉(渐变虚线卡 + blob + 主/副文案) Task 1
description + tip API Task 1
主页 tip Task 2
comps tip 演示 Task 2
list 无 tip 不占位 Task 2 Step 3 / Task 3
三墙色、无 #10b981 Task 1 Step 2
不引入 E 变体 / 不引真实 Vant 全计划未包含

Out of scope

  • 横向紧凑变体 E
  • 真实 @vant/weapp 依赖
  • 改业务菜单数据源(菜单仍为空数组)