Spaces:
Sleeping
Sleeping
File size: 2,966 Bytes
bb9df9e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | <!--
多图上传组件
@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: () => [],
},
/**
* 文件上传数量限制
*/
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: 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>
|