---
title: "ImageUploader 图片上传"
description: "带本地预览的受控图片选择器"
category: Form
status: beta
since: 0.3.4
tags: [image, upload, form]
syncStatus: reviewed
verified: true
---

## 用法

### 基础
`max` 限定总数，`accept` 限定类型。
::::TuffDemoWrapper{demo="ImageUploaderImageUploaderDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { ref } from 'vue'

  const files = ref([])
  </script>

  <template>
    <TxImageUploader v-model="files" :max="4" accept="image/png,image/jpeg" />
  </template>
---
::::

### 上传新选择的图片
没有 `add` 事件：监听 `change`，筛选带 `file` 的记录。

```vue
<script setup lang="ts">
import type { ImageUploaderFile } from '@talex-touch/tuffex/image-uploader'
import { ref } from 'vue'

const images = ref<ImageUploaderFile[]>([])

async function onChange(next: ImageUploaderFile[]) {
  const localFiles = next.filter(item => item.file)
  await uploadImages(localFiles.map(item => item.file!))
}
</script>

<template>
  <TxImageUploader v-model="images" accept="image/*" :max="6" @change="onChange" />
</template>
```

### 已有的远程图片
没有 `file` 的记录可以预览和删除，组件不会释放它们的 URL。

```vue
<script setup lang="ts">
const images = ref([
  { id: 'remote-1', url: cdnUrl, name: '封面图' },
])
</script>
```

### 最佳实践

- 只需要图片预览时用 `ImageUploader`；需要通用文件、拖拽、文件大小或 `add` 事件时用 `FileUploader`。
- 服务端仍要校验 MIME、尺寸、大小与内容；`accept` 只是浏览器提示。
- 远程记录使用持久 id；本地生成的 id 只在当前界面会话内有效。
- 上传成功后，用远程 URL 记录替换本地 object URL 记录；不要手动释放组件创建的 URL。
- 让 `max` 与后端上限保持一致。

## API 参考

### 属性

| 属性名 | 类型 | 默认值 | 说明 |
|------|------|---------|------|
| `modelValue` | `ImageUploaderFile[]` | 必填 | 图片列表（受控）。 |
| `multiple` | `boolean` | `true` | 透传给原生 input。 |
| `accept` | `string` | `'image/*'` | 可接受的图片类型，透传给原生 input。 |
| `disabled` | `boolean` | `false` | 禁止添加与删除。 |
| `max` | `number` | `9` | 图片总数上限。 |
| `uploadText` | `string` | `'Upload'` | 添加块的文案，可覆盖以本地化。 |
| `removeLabel` | `(name?: string) => string` | `Remove {name}` | 生成删除按钮的 `aria-label`，可覆盖以本地化。 |

### 事件

| 事件名 | 参数 | 说明 |
|------|------|------|
| `update:modelValue` | `ImageUploaderFile[]` | 新增或删除后的完整列表。 |
| `change` | `ImageUploaderFile[]` | 随 `update:modelValue` 一起触发，参数相同。 |
| `remove` | `{ id: string, value: ImageUploaderFile[] }` | 被删除的 id 与删除后的列表。 |

### 类型

`ImageUploaderFile`，列表中的一项：

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | `string` | 稳定 id，用作预览 key 与删除参数。 |
| `url` | `string` | 预览地址；本地文件为 object URL。 |
| `name` | `string` | 可选名称，用于 alt 文本与删除标签。 |
| `file` | `File` | 可选原始文件，本地新选的图片才有。 |

## 概述

- 添加块是原生 `<button type="button">`，禁用或达到 `max` 时不可点击；隐藏的 `<input type="file">` 接收 `multiple`、`accept`、`disabled`。
- 本地预览使用 `URL.createObjectURL`；每次选择后清空原生 input，同一文件可以再次选择。
- `multiple` 时新增数量受剩余容量限制；单选时新图片替换原图片。
- 新增依次派发 `update:modelValue`、`change`；删除依次派发 `update:modelValue`、`remove`、`change`。
- 组件只释放自己创建的 object URL：删除时释放对应 URL，卸载时全部释放；远程 URL 与父级创建的 blob URL 由调用方负责。
- 预览图以 `name` 作为 alt，未命名时 alt 为空。

## 技术实现

- 源码：`packages/tuffex/packages/components/src/image-uploader/`。

<TuffDocSourceLink />
