根据当前环境变量获取预览地址
export const getPreviewUrl = () => import.meta.env.VITE_UPLOAD_PREVIEW_URL
下载Blob文件
参见此处
源文件
type computeFileUlrFunc = (upload: UploadResult) => string
const emit = defineEmits(['update:value'])
const slots = useSlots()
console.log('slots: ', slots)
const props = defineProps({
value: {
type: Array as () => UploadResult[],
default: () => [],
},
type: {
type: String as PropType<'file' | 'picture'>,
validator: (type: string) => ['file', 'picture'].includes(type),
default: 'file',
},
limit: {
type: Number,
default: () => undefined,
},
accept: {
type: String,
},
disabled: {
type: Boolean,
default: false,
},
onSuccess: {
type: Function as PropType<(res: UploadResult) => void>,
},
showFileList: {
type: Boolean,
default: true,
},
btnShow: {
type: Object,
default: () => ({ view: true, downLoad: true, delete: true }),
},
})
const _accept = computed(() => {
if (props.type === 'picture')
return 'image/*'
else return props.accept
})
const fileList = ref<UploadResult[]>([])
const uploadRef = ref()
const canUpload = computed(() => {
if (props.limit === undefined)
return true
return fileList.value.length < props.limit
})
const _fileList: ComputedRef<UploadUserFile[]> = computed(() =>
fileList.value.map(e => ({
name: e.fileName,
status: 'success',
url: e.fileUrl,
})),
)
const getFileUrl = computed<computeFileUlrFunc>(
() => upload => getPreviewUrl() + upload.fileUrl,
)
watchEffect(() => {
fileList.value = props.value
})
const customUpload = async(params) => {
const res = await uploadTempFile(params.file)
if (isFunction(props.onSuccess))
props.onSuccess(res)
fileList.value.push(res)
emit('update:value', fileList.value)
}
const handleOnExceed = () => {
ElMessage.warning(`超过最大上传数量${props.limit}`)
}
const handleRemove = (index: number) => {
fileList.value.splice(index, 1)
emit('update:value', fileList.value)
}
const downloadFile = (file: UploadResult) => {
downloadByUrl(getPreviewUrl() + file.fileUrl, file.fileName)
}
const handlePreview = (index: number) => {
// viewerApi({
// options: {
// toolbar: true,
// initialViewIndex: index,
// movable: false,
// zIndex: 9999,
// },
// images: fileList.value.map(e => getFileUrl.value(e)),
// })
}
</script>
<template>
<div>
<template v-if="type === 'file'">
<el-upload
ref="uploadRef"
action="#"
:http-request="customUpload"
:show-file-list="false"
:multiple="true"
:on-exceed="handleOnExceed"
:limit="limit"
:file-list="_fileList"
:disabled="disabled"
:accept="_accept"
>
<el-button :disabled="!canUpload" type="primary">
上传文件
</el-button>
</el-upload>
<template v-if="showFileList">
<transition-group v-if="fileList.length > 0" class="file-list" name="el-fade-in" tag="ul">
<li v-for="(file, index) in fileList" :key="file.fileUrl" class="file-list__item">
<el-link :underline="false" target="_blank" class="ml-5px" @click="downloadFile(file)">
<span>{{ file.fileName }}</span>
</el-link>
<div class="mr-10px">
<el-link :underline="false" type="danger" @click="handleRemove(index)">
删除
</el-link>
</div>
</li>
</transition-group>
</template>
</template>
<template v-else-if="type === 'picture'">
<div class="flex mt-1">
<transition-group class="picture-list" name="el-fade-in" tag="div">
<div v-for="(file, index) in fileList" :key="file.fileUrl" class="picture-list__item">
<img :src="getFileUrl(file)" alt="pic" class="picture-list__item-thumbnail">
<span class="picture-list__item-actions">
<span @click="handlePreview(index)">
<IconEpView v-show="btnShow.view" />
</span>
<span @click="() => { }">
下载
</span>
<span v-show="btnShow.delete" @click="handleRemove(index)">
删除
</span>
</span>
</div>
</transition-group>
<el-upload
ref="uploadRef"
:http-request="customUpload"
:show-file-list="false"
:multiple="true"
:limit="limit"
:on-exceed="handleOnExceed"
:file-list="_fileList"
:disabled="disabled"
:accept="_accept"
action="#"
>
<div v-if="canUpload" class="upload-picture-card">
<IconEpPlus class="text-28px inline-block" />
</div>
</el-upload>
</div>
</template>
</div>
</template>