Files
element-plus/packages/components/upload/src/useHandlers.ts
Alan Wang 23712260f0 docs: [el-upload]add example of setting on-exceed to cover the old file (#4861)
* docs: [el-upload]add example of seting on-exceed to cover the old file

* Update packages/components/upload/src/useHandlers.ts

Co-authored-by: btea <2356281422@qq.com>

* Update docs/examples/upload/limit-cover.vue

Co-authored-by: btea <2356281422@qq.com>

Co-authored-by: btea <2356281422@qq.com>
2021-12-21 09:27:52 +08:00

182 lines
4.4 KiB
TypeScript

import { ref, watch } from 'vue'
import { NOOP } from '@vue/shared'
import cloneDeep from 'lodash/cloneDeep'
// Inline types
import type {
ListType,
UploadFile,
UploadStatus,
ElFile,
ElUploadProgressEvent,
IUseHandlersProps,
} from './upload.type'
type UploadRef = {
abort: (file: UploadFile) => void
upload: (file: ElFile) => void
}
// helpers
function getFile(rawFile: ElFile, uploadFiles: UploadFile[]) {
return uploadFiles.find((file) => file.uid === rawFile.uid)
}
function genUid(seed: number) {
return Date.now() + seed
}
export default (props: IUseHandlersProps) => {
const uploadFiles = ref<UploadFile[]>([])
const uploadRef = ref<UploadRef>(null)
let tempIndex = 1
function abort(file: UploadFile) {
uploadRef.value.abort(file)
}
function clearFiles(
status: UploadStatus[] = ['ready', 'uploading', 'success', 'fail']
) {
uploadFiles.value = uploadFiles.value.filter((row) => {
return !status.includes(row.status)
})
}
function handleError(err: Error, rawFile: ElFile) {
const file = getFile(rawFile, uploadFiles.value)
file.status = 'fail'
uploadFiles.value.splice(uploadFiles.value.indexOf(file), 1)
props.onError(err, file, uploadFiles.value)
props.onChange(file, uploadFiles.value)
}
function handleProgress(ev: ElUploadProgressEvent, rawFile: ElFile) {
const file = getFile(rawFile, uploadFiles.value)
props.onProgress(ev, file, uploadFiles.value)
file.status = 'uploading'
file.percentage = ev.percent || 0
}
function handleSuccess(res: any, rawFile: ElFile) {
const file = getFile(rawFile, uploadFiles.value)
if (file) {
file.status = 'success'
file.response = res
props.onSuccess(res, file, uploadFiles.value)
props.onChange(file, uploadFiles.value)
}
}
function handleStart(rawFile: ElFile) {
const uid = genUid(tempIndex++)
rawFile.uid = uid
const file: UploadFile = {
name: rawFile.name,
percentage: 0,
status: 'ready',
size: rawFile.size,
raw: rawFile,
uid,
}
if (props.listType === 'picture-card' || props.listType === 'picture') {
try {
file.url = URL.createObjectURL(rawFile)
} catch (err) {
console.error('[Element Error][Upload]', err)
props.onError(err, file, uploadFiles.value)
}
}
uploadFiles.value.push(file)
props.onChange(file, uploadFiles.value)
}
function handleRemove(file: UploadFile, raw: ElFile) {
if (raw) {
file = getFile(raw, uploadFiles.value)
}
const revokeObjectURL = () => {
if (file.url && file.url.indexOf('blob:') === 0) {
URL.revokeObjectURL(file.url)
}
}
const doRemove = () => {
abort(file)
const fileList = uploadFiles.value
fileList.splice(fileList.indexOf(file), 1)
props.onRemove(file, fileList)
revokeObjectURL()
}
if (!props.beforeRemove) {
doRemove()
} else if (typeof props.beforeRemove === 'function') {
const before = props.beforeRemove(file, uploadFiles.value)
if (before instanceof Promise) {
before
.then(() => {
doRemove()
})
.catch(NOOP)
} else if (before !== false) {
doRemove()
}
}
}
function submit() {
uploadFiles.value
.filter((file) => file.status === 'ready')
.forEach((file) => {
uploadRef.value.upload(file.raw)
})
}
watch(
() => props.listType,
(val: ListType) => {
if (val === 'picture-card' || val === 'picture') {
uploadFiles.value = uploadFiles.value.map((file) => {
if (!file.url && file.raw) {
try {
file.url = URL.createObjectURL(file.raw)
} catch (err) {
props.onError(err, file, uploadFiles.value)
}
}
return file
})
}
}
)
watch(
() => props.fileList,
(fileList: UploadFile[]) => {
uploadFiles.value = fileList.map((file) => {
const cloneFile = cloneDeep(file)
return {
...cloneFile,
uid: file.uid || genUid(tempIndex++),
status: file.status || 'success',
}
})
},
{
immediate: true,
deep: true,
}
)
return {
abort,
clearFiles,
handleError,
handleProgress,
handleStart,
handleSuccess,
handleRemove,
submit,
uploadFiles,
uploadRef,
}
}