✅ 背景说明

在企业项目中,页面级容器通常包含以下元素:

  • 页面标题 / 操作按钮 / 统一内边距;

  • 网络请求状态处理(loading / error / success);

  • 空内容兜底提示;

  • 主体内容区(可嵌套组件或列表);

如果每个页面手动处理标题、状态和布局,代码重复度高,且易于维护困难。因此封装一个 PageWrapper 页面级容器组件,将统一状态处理、布局样式与业务插槽结合,是现代前端项目的重要工程实践。


🧱 一、组件目标功能

  • 接收 title 页面标题;

  • 接收 status 页面状态(loading / error / empty / success);

  • 可配置重试函数;

  • 提供 slot 渲染主内容区域;

  • 自动处理边距、结构、兜底 UI。


📦 二、组件结构定义

@Component
struct PageWrapper {
  @Prop title: string = '';
  @Prop status: 'loading' | 'error' | 'empty' | 'success' = 'loading';
  @Prop errorMessage: string = '页面加载失败';
  @Prop emptyMessage: string = '暂无内容';
  @Prop onRetry: () => void = () => {};
  @Slot content?: () => void;
}

🧩 三、组件 UI 构建逻辑

build() {
  Column({ space: 10 }) {
    // 标题栏
    if (this.title) {
      Text(this.title)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .padding({ bottom: 10 })
    }

    // 状态处理
    if (this.status === 'loading') {
      Progress().type(ProgressType.Ring).margin({ top: 50 })
      return;
    }

    if (this.status === 'error') {
      ResultStatus({
        status: 'error',
        message: this.errorMessage,
        onRetry: this.onRetry
      })
      return;
    }

    if (this.status === 'empty') {
      EmptyView({ type: 'empty', message: this.emptyMessage })
      return;
    }

    // 主体内容插槽
    if (this.status === 'success' && this.content) {
      this.content!()
    }
  }.padding(20)
}

🧪 四、父组件调用示例

@Component
struct OrderPage {
  @State status: 'loading' | 'success' | 'error' | 'empty' = 'loading';
  @State orders: string[] = [];

  async aboutToAppear() {
    this.loadOrders();
  }

  async loadOrders() {
    this.status = 'loading';
    try {
      await delay(500);
      this.orders = ['订单A', '订单B', '订单C'];
      this.status = this.orders.length ? 'success' : 'empty';
    } catch {
      this.status = 'error';
    }
  }

  build() {
    PageWrapper({
      title: '订单列表',
      status: this.status,
      errorMessage: '订单加载失败',
      emptyMessage: '暂无订单',
      onRetry: () => this.loadOrders()
    }) {
      Column({ space: 6 }) {
        ForEach(this.orders, (o) => Text(o).fontSize(16), o => o)
      }
    }
  }
}

⚠️ 五、常见问题与建议

问题 原因 建议
插槽无效 插槽未定义或 status 不为 success 确保插槽仅在 success 时调用
标题样式不统一 每页标题手写 使用 PageWrapper 统一输出标题样式
多页面逻辑雷同 每页都写 loading / error 抽离公共状态管理与布局封装 PageWrapper 是核心目的

🚀 六、拓展建议

  • 添加右上角操作按钮插槽(如“新增”、“筛选”);

  • 支持 Footer 内容插槽;

  • 支持内容滚动容器封装;

  • 页面自动回顶部控制;

  • ResultStatus / SkeletonList 联动支持内容前骨架加载效果。


✅ 小结

本篇构建了一个具备标题、状态统一处理与内容插槽能力的页面级容器组件 PageWrapper,极大简化页面逻辑代码,提升产品一致性与开发效率,是工程化落地中不可或缺的一环

下一篇将进入第8篇:

《构建表格工具组件 TableHeaderTool(搜索 + 筛选 + 批量操作统一处理)》

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐