【HarmonyOS 5.0.0 或以上】构建上传组件 Uploader:支持图片预览 / 多图选择 / 文件校验

🎯 目标

构建一个灵活的上传组件 CommonUploader,适用于用户头像、作业提交、资源上传等场景,支持:

  • 单图 / 多图上传

  • 图片预览 / 删除 / 顺序展示

  • 文件类型、大小校验

  • 支持文件读取后预处理(如压缩、转码)

  • 拓展支持异步上传与状态反馈


🧱 样式交互示意

[ + 上传图片 ]
🖼️ [图1] ❌   🖼️ [图2] ❌

🧰 组件实现:CommonUploader.ets

@Component
export struct CommonUploader {
  @Prop maxCount: number = 5
  @Prop fileList: Array<string> = []
  @Prop accept: Array<string> = ['image/*']
  @Prop maxSizeMB: number = 5
  @Prop onSelect: (files: string[]) => void = () => {}
  @Prop onDelete: (index: number) => void = () => {}

  build() {
    Wrap({ spacing: 12 }) {
      // 图片展示列表
      ForEach(this.fileList, (url: string, index: number) => {
        Stack()
          .width(80)
          .height(80)
          .backgroundImage(url)
          .backgroundImageSize(ImageSize.Cover)
          .borderRadius(6) {
          Image($r('app.media.icon_close'))
            .width(16)
            .height(16)
            .align(Alignment.TopEnd)
            .margin({ top: 4, right: 4 })
            .onClick(() => this.onDelete(index))
        }
      })

      // 添加按钮
      if (this.fileList.length < this.maxCount) {
        Column()
          .width(80)
          .height(80)
          .backgroundColor('#f5f5f5')
          .borderRadius(6)
          .alignItems(HorizontalAlign.Center)
          .justifyContent(FlexAlign.Center)
          .onClick(() => this.handleSelect()) {
          Image($r('app.media.icon_upload')).width(24).height(24)
          Text('上传').fontSize(12).fontColor('#888')
        }
      }
    }
  }

  private async handleSelect() {
    // 模拟文件选择 + base64 预览(实际开发中接入系统API)
    try {
      const files = await mockPickImages(this.accept, this.maxCount - this.fileList.length)

      const validFiles = files.filter(f => f.size / 1024 / 1024 <= this.maxSizeMB)
      const urls = validFiles.map(f => f.base64)

      this.onSelect(urls)
    } catch (e) {
      console.error('选择失败', e)
    }
  }
}

说明:此处的 mockPickImages 为模拟文件选择逻辑,实际部署时请结合 chooseImage / filePicker 等系统 API 获取文件内容与 URL。


📦 使用示例

@Entry
@Component
struct DemoUploader {
  @State imgs: string[] = []

  build() {
    Column({ space: 16 }) {
      CommonUploader({
        fileList: this.imgs,
        onSelect: (newFiles: string[]) => this.imgs = [...this.imgs, ...newFiles],
        onDelete: (i: number) => this.imgs.splice(i, 1)
      })

      Text(`当前共上传 ${this.imgs.length} 张图`).fontSize(14).fontColor('#333')
    }.padding(20)
  }
}

✨ 可扩展能力建议

功能说明
文件类型校验限制为 image / zip / pdf 等多种类型
上传状态管理支持文件上传中、失败、成功等状态标记
上传服务集成将选中文件通过 fetch / uploadFile 上传至服务器
拖拽上传支持PC端支持拖入文件上传,移动端兼容点击/拍照

📘 下一篇预告

第20篇:【HarmonyOS 5.0.0 或以上】构建数字输入组件 NumberInput:支持加减按钮 / 最大最小限制 / 禁用状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值