Files
vue3-element-admin/src/components/Upload/MultiUpload.vue
haoxr 764e334ea0 refactor: 自动导入移除手动导入
Former-commit-id: 696a377c0a3faddcfd95a38122937f2bf25bc881
2023-03-11 21:24:46 +08:00

140 lines
2.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--
多图上传组件
@author: youlaitech
@date 2022/11/20
-->
<template>
<el-upload
v-model:file-list="fileList"
list-type="picture-card"
:before-upload="handleBeforeUpload"
:http-request="handleUpload"
:on-remove="handleRemove"
:on-preview="previewImg"
:limit="props.limit"
>
<i-ep-plus />
</el-upload>
<el-dialog v-model="dialogVisible">
<img w-full :src="previewImgUrl" alt="Preview Image" />
</el-dialog>
</template>
<script setup lang="ts">
import {
UploadRawFile,
UploadRequestOptions,
UploadUserFile,
UploadFile,
UploadProps
} from 'element-plus';
import { uploadFileApi, deleteFileApi } from '@/api/file';
const emit = defineEmits(['update:modelValue']);
const props = defineProps({
/**
* 文件路径集合
*/
modelValue: {
type: Array<string>,
default: [] as Array<string>
},
/**
* 文件上传数量限制
*/
limit: {
type: Number,
default: 5
}
});
const previewImgUrl = ref('');
const dialogVisible = ref(false);
const fileList = ref([] as UploadUserFile[]);
watch(
() => props.modelValue,
(newVal: string[]) => {
const filePaths = fileList.value.map(file => file.url);
// 监听modelValue文件集合值未变化时跳过赋值
if (
filePaths.length > 0 &&
filePaths.length === newVal.length &&
filePaths.every(x => newVal.some(y => y === x)) &&
newVal.every(y => filePaths.some(x => x === y))
) {
return;
}
fileList.value = newVal.map(filePath => {
return { url: filePath } as UploadUserFile;
});
},
{ immediate: true }
);
/**
* 自定义图片上传
*
* @param params
*/
async function handleUpload(options: UploadRequestOptions): Promise<any> {
// 上传API调用
const { data: fileInfo } = await uploadFileApi(options.file);
// 上传成功需手动替换文件路径为远程URL否则图片地址为预览地址 blob:http://
const fileIndex = fileList.value.findIndex(
file => file.uid == (options.file as any).uid
);
fileList.value.splice(fileIndex, 1, {
name: fileInfo.name,
url: fileInfo.url
} as UploadUserFile);
emit(
'update:modelValue',
fileList.value.map(file => file.url)
);
}
/**
* 删除图片
*/
function handleRemove(removeFile: UploadFile) {
const filePath = removeFile.url;
if (filePath) {
deleteFileApi(filePath).then(() => {
// 删除成功回调
emit(
'update:modelValue',
fileList.value.map(file => file.url)
);
});
}
}
/**
* 限制用户上传文件的格式和大小
*/
function handleBeforeUpload(file: UploadRawFile) {
if (file.size > 2 * 1048 * 1048) {
ElMessage.warning('上传图片不能大于2M');
return false;
}
return true;
}
/**
* 预览图片
*/
const previewImg: UploadProps['onPreview'] = uploadFile => {
previewImgUrl.value = uploadFile.url!;
dialogVisible.value = true;
};
</script>