🎯 目标
构建一个灵活的上传组件 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:支持加减按钮 / 最大最小限制 / 禁用状态