Files
vue3-element-admin/src/components/Upload/MultiUpload.vue

135 lines
2.8 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.
<!-- 多图上传组件 -->
<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 FileAPI from "@/api/file";
const emit = defineEmits(["update:modelValue"]);
const props = defineProps({
/**
* 文件路径集合
*/
modelValue: {
type: Array<string>,
default: () => [],
},
/**
* 文件上传数量限制
*/
limit: {
type: Number,
default: 10,
},
});
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 = await FileAPI.upload(options.file);
// 上传成功需手动替换文件路径为远程URL否则图片地址为预览地址 blob:http://
const fileIndex = fileList.value.findIndex(
(file) => file.uid == (options.file as any).uid
);
fileList.value.splice(fileIndex, 1, {
name: data.name,
url: data.url,
} as UploadUserFile);
emit(
"update:modelValue",
fileList.value.map((file) => file.url)
);
}
/**
* 删除图片
*/
function handleRemove(removeFile: UploadFile) {
const filePath = removeFile.url;
if (filePath) {
FileAPI.deleteByPath(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>