업로드
업로드 (Upload)
출처: 문서
본문
클릭 또는 드래그 앤 드롭으로 파일을 업로드하는 컴포넌트예요.
기본 사용법
slot을 사용해 업로드 버튼의 타입과 텍스트를 커스터마이즈할 수 있어요. limit와 on-exceed를 설정하면 허용되는 최대 업로드 개수를 제한하고, 한도를 초과했을 때의 동작을 지정할 수 있어요. 그리고 before-remove 훅에서 파일 삭제를 중단할 수도 있죠.
jpg/png파일, 크기 500KB 미만- element-plus-logo.svg (press delete to remove)
- element-plus-logo2.svg (press delete to remove)
<template>
<el-upload
v-model:file-list="fileList"
action="https://run.mocky.io/v3/9d059bf9-4660-45f9-925d-a31b31d8f1c5"
:limit="3"
:on-exceed="handleExceed"
:before-remove="beforeRemove"
@remove="handleRemove"
@preview="handlePreview"
>
<el-button type="primary">Click to upload</el-button>
<template #tip>
<div class="el-upload__tip">
jpg/png files with a size less than 500KB.
</div>
</template>
</el-upload>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { UploadProps, UploadUserFile } from 'element-plus'
const fileList = ref<UploadUserFile[]>([
{
name: 'element-plus-logo.svg',
url: 'https://element-plus.org/images/element-plus-logo.svg',
},
{
name: 'element-plus-logo2.svg',
url: 'https://element-plus.org/images/element-plus-logo.svg',
},
])
const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
console.log(file, uploadFiles)
}
const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
console.log(uploadFile)
}
const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
ElMessage.warning(
`The limit is 3, you selected ${files.length} files this time, add up to ${
files.length + uploadFiles.length
} totally`
)
}
const beforeRemove: UploadProps['beforeRemove'] = (uploadFile, uploadFiles) => {
return ElMessageBox.confirm(
`Cancel the transfer of ${uploadFile.name} ?`
).then(
() => true,
() => false
)
}
</script>
이전 파일 덮어쓰기 (Cover Previous File)
limit와 on-exceed를 설정하면 새 파일을 선택할 때 이전 파일을 자동으로 대체해요.
- upload to server, limit 1 file, new file will cover the old file
<template>
<el-upload
ref="upload"
v-model:file-list="fileList"
action="#"
:limit="1"
:on-exceed="handleExceed"
>
<el-button type="primary">Click to upload</el-button>
<template #tip>
<div class="el-upload__tip">
upload to server, limit 1 file, new file will cover the old file
</div>
</template>
</el-upload>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { genFileId } from 'element-plus'
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
const upload = ref<UploadInstance>()
const handleExceed: UploadProps['onExceed'] = (files) => {
upload.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
upload.value!.handleStart(file)
}
const submitUpload = () => {
upload.value!.submit()
}
</script>
사용자 아바타 (User Avatar)
before-upload 훅을 사용해 업로드 파일의 형식과 크기를 제한할 수 있어요.
<template>
<el-upload
class="avatar-uploader"
action="https://run.mocky.io/v3/9d059bf9-4660-45f9-925d-a31b31d8f1c5"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import type { UploadProps } from 'element-plus'
const imageUrl = ref('')
const handleAvatarSuccess: UploadProps['onSuccess'] = (
response,
uploadFile
) => {
imageUrl.value = URL.createObjectURL(uploadFile.raw!)
}
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
if (rawFile.type !== 'image/jpeg') {
ElMessage.error('Avatar picture must be JPG format!')
return false
} else if (rawFile.size / 1024 / 1024 > 2) {
ElMessage.error('Avatar picture size can not exceed 2MB!')
return false
}
return true
}
</script>
포토 월 (Photo Wall)
list-type을 사용해 fileList 스타일을 바꿀 수 있어요.
<template>
<el-upload
v-model:file-list="fileList"
action="https://run.mocky.io/v3/9d059bf9-4660-45f9-925d-a31b31d8f1c5"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
>
<el-icon><Plus /></el-icon>
</el-upload>
<el-dialog v-model="dialogVisible">
<img w-full :src="dialogImageUrl" alt="Preview Image" />
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Delete, Download, Plus, ZoomIn } from '@element-plus/icons-vue'
import type { UploadFile } from 'element-plus'
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const disabled = ref(false)
const handleRemove = (file: UploadFile) => {
console.log(file)
}
const handlePictureCardPreview = (file: UploadFile) => {
dialogImageUrl.value = file.url!
dialogVisible.value = true
}
const handleDownload = (file: UploadFile) => {
console.log(file)
}
</script>
썸네일이 있는 파일 목록 (File List with Thumbnail)
jpg/png파일, 크기 500kb 미만- food.jpeg (press delete to remove)
- food2.jpeg (press delete to remove)
<template>
<el-upload
v-model:file-list="fileList"
class="upload-demo"
action="https://run.mocky.io/v3/9d059bf9-4660-45f9-925d-a31b31d8f1c5"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
>
<el-button type="primary">Click to upload</el-button>
<template #tip>
<div class="el-upload__tip">
jpg/png files with a size less than 500kb
</div>
</template>
</el-upload>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadProps, UploadUserFile } from 'element-plus'
const fileList = ref<UploadUserFile[]>([
{
name: 'food.jpeg',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
},
{
name: 'food2.jpeg',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
},
])
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
console.log(uploadFile, uploadFiles)
}
const handlePreview: UploadProps['onPreview'] = (file) => {
console.log(file)
}
</script>
파일 목록 제어 (File List Control)
on-change 훅 함수를 사용해 업로드 파일 목록을 제어할 수 있어요.
jpg/png파일, 크기 500kb 미만- food.jpeg (press delete to remove)
- food2.jpeg (press delete to remove)
<template>
<el-upload
v-model:file-list="fileList"
class="upload-demo"
action="https://run.mocky.io/v3/9d059bf9-4660-45f9-925d-a31b31d8f1c5"
:on-change="handleChange"
>
<el-button type="primary">Click to upload</el-button>
</el-upload>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadProps, UploadUserFile } from 'element-plus'
const fileList = ref<UploadUserFile[]>([
{
name: 'food.jpeg',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
},
{
name: 'food2.jpeg',
url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
},
])
const handleChange: UploadProps['onChange'] = (uploadFile, uploadFiles) => {
fileList.value = fileList.value.slice(-3)
}
</script>
드래그 업로드 (Drag to Upload)
파일을 특정 영역으로 드래그해서 업로드할 수 있어요.
jpg/png파일, 크기 500kb 미만
<template>
<el-upload
class="upload-demo"
drag
action="https://run.mocky.io/v3/9d059bf9-4660-45f9-925d-a31b31d8f1c5"
multiple
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
Drop file here or <em>click to upload</em>
</div>
<template #tip>
<div class="el-upload__tip">
jpg/png files with a size less than 500kb
</div>
</template>
</el-upload>
</template>
<script setup lang="ts">
import { UploadFilled } from '@element-plus/icons-vue'
</script>
디렉토리 업로드 (Upload Directory) 2.13.1
directory prop으로 폴더 업로드를 활성화할 수 있어요. 활성화하면 폴더만 선택할 수 있고, 폴더를 선택하면 폴더 안의 파일들이 평탄화(flatten)되어 사용돼요.
<template>
<el-upload
action="#"
directory
:auto-upload="false"
:on-change="handleChange"
>
<el-button type="primary">Select folder</el-button>
</el-upload>
</template>
<script setup lang="ts">
import { UploadFilled } from '@element-plus/icons-vue'
import type { UploadFile, UploadFiles } from 'element-plus'
const handleChange = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
console.log(uploadFile, uploadFiles)
}
</script>
수동 업로드 (Manual Upload)
- upload to server,
jpg/png파일, 크기 500kb 미만
<template>
<el-upload
ref="uploadRef"
v-model:file-list="fileList"
action="https://run.mocky.io/v3/9d059bf9-4660-45f9-925d-a31b31d8f1c5"
:auto-upload="false"
>
<template #trigger>
<el-button type="primary">select file</el-button>
</template>
<el-button class="ml-3" type="success" @click="submitUpload">
upload to server
</el-button>
<template #tip>
<div class="el-upload__tip">
jpg/png files with a size less than 500kb
</div>
</template>
</el-upload>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { UploadInstance } from 'element-plus'
const uploadRef = ref<UploadInstance>()
const submitUpload = () => {
uploadRef.value!.submit()
}
</script>
API
Attributes
| Name | Description | Type | Default |
|---|---|---|---|
| action (required) | request URL. | string | # |
| headers | request headers. | object | — |
| method | set upload request method. | string | post |
| multiple | whether uploading multiple files is permitted. | boolean | false |
| data | additions options of request. support Awaitable data and Function since v2.3.13. | object / Function | {} |
| name | key name for uploaded file. | string | file |
| with-credentials | whether cookies are sent. | boolean | false |
| show-file-list | whether to show the uploaded file list. | boolean | true |
| drag | whether to activate drag and drop mode. | boolean | false |
| accept | accepted file types, will not work when thumbnail-mode === true. | string | '' |
| crossorigin | native attribute crossorigin. | enum | — |
| on-preview | hook function when clicking the uploaded files. | Function | — |
| on-remove | hook function when files are removed. | Function | — |
| on-success | hook function when uploaded successfully. | Function | — |
| on-error | hook function when some errors occurs. | Function | — |
| on-progress | hook function when some progress occurs. | Function | — |
| on-change | hook function when select file or upload file success or upload file fail. | Function | — |
| on-exceed | hook function when limit is exceeded. | Function | — |
| before-upload | hook function before uploading with the file to be uploaded as its parameter. If false is returned or a Promise is returned and then is rejected, uploading will be aborted. | Function | — |
| before-remove | hook function before removing a file with the file and file list as its parameters. If false is returned or a Promise is returned and then is rejected, removing will be aborted. | Function | — |
| file-list / v-model:file-list | default uploaded files. | array | [] |
| list-type | type of file list. | enum | text |
| auto-upload | whether to auto upload file. | boolean | true |
| http-request | override default xhr behavior, allowing you to implement your own upload-file's request. | Function | ajaxUpload (see) |
| disabled | whether to disable upload. | boolean | false |
| limit | maximum number of uploads allowed. | number | — |
| directory (2.13.1) | whether to support uploading directory. After enabling it, only folders can be selected, and after selecting a folder, the files within the folder will be flattened. | boolean | false |
Slots
| Name | Description | Type |
|---|---|---|
| default | customize default content. | - |
| trigger | content which triggers file dialog. | - |
| tip | content of tips. | - |
| file | content of thumbnail template. | object |
Exposes
| Name | Description | Type |
|---|---|---|
| abort | cancel upload request. When a file is specified, abort the corresponding pending upload; when no file is specified, abort all pending uploads. | Function |
| submit | upload the file list manually. | Function |
| clearFiles | clear the file list (this method is not supported in the before-upload hook). | Function |
| handleStart | select the file manually. | Function |
| handleRemove | remove the file manually. file and rawFile has been merged. rawFile will be removed in v2.2.0. | Function |
타입 선언 (Type Declarations)
type UploadFiles = UploadFile[]
type UploadUserFile = Omit<UploadFile, 'status' | 'uid'> &
Partial<Pick<UploadFile, 'status' | 'uid'>>
type UploadStatus = 'ready' | 'uploading' | 'success' | 'fail'
type Awaitable<T> = Promise<T> | T
type Mutable<T> = { -readonly [P in keyof T]: T[P] }
interface UploadFile {
name: string
percentage?: number
status: UploadStatus
size?: number
response?: unknown
uid: number
url?: string
raw?: UploadRawFile
}
interface UploadProgressEvent extends ProgressEvent {
percent: number
}
interface UploadRawFile extends File {
uid: number
isDirectory?: boolean
}
interface UploadRequestOptions {
action: string
method: string
data: Record<string, string | Blob>
filename: string
file: UploadRawFile
headers: Headers | Record<string, string>
onError: (evt: UploadAjaxError) => void
onProgress: (evt: UploadProgressEvent) => void
onSuccess: (response: any) => void
withCredentials: boolean
}