封装了一个element ui多图上传组件,支持v-model
<template>
<div
class="uploader"
:exceed="
$props.value.length >= $props.limit ||
(pending && $props.value.length === $props.limit - 1)
"
>
<el-upload
action=""
list-type="picture-card"
:on-success="handleOnUploadSuccess"
:on-error="handleOnUploadError"
:on-exceed="handleOnUploadExceed"
:on-remove="handleOnRemove"
:before-upload="handleBeforeUpload"
:http-request="handleUploadHttpRequest"
:file-list="$props.value"
:on-preview="handlePreview"
:show-file-list="true"
:limit="$props.limit"
accept="image/png,image/gif,image/jpg,image/jpeg"
>
<i class="el-icon-plus"></i>
</el-upload>
<ElImageViewer
v-if="showViewer"
:on-close="() => (showViewer = false)"
:url-list="[viewerUrl]"
></ElImageViewer>
</div>
</template>
<script>
import ElImageViewer from "element-ui/packages/image/src/image-viewer";
export default {
components: { ElImageViewer },
props: {
value: { type: Array, default: () => [] },
api: Function,
fileName: { type: String, default: "file" },
limit: { type: Number, default: 3 },
size: { type: Number, default: 5 }
},
model: {
prop: "value",
event: "change"
},
data() {
return {
pending: false,
viewerUrl: "",
showViewer: false,
attachmentFetching: true,
attachmentUploading: false,
attachmentTooLarge: false,
attachmentUploadFormData: new FormData()
};
},
methods: {
handleOnUploadSuccess(response, file, fileList) {
this.attachmentUploadFormData.delete(this.$props.fileName);
this.attachmentUploading = false;
this.$message.success("上传成功");
fileList[fileList.length - 1].url = response.data;
fileList[fileList.length - 1].isDefault = 1;
this.$emit("change", fileList);
this.pending = false;
},
handleOnUploadError(error) {
this.attachmentUploadFormData.delete(this.$props.fileName);
this.attachmentUploading = false;
this.$message.error(error.msg || error);
this.pending = false;
},
handleBeforeUpload(file) {
const isLt2M = file.size / 1024 / 1024 < this.$props.size;
if (!isLt2M) {
this.attachmentTooLarge = true;
this.$message.error(`上传图片大小不能超过 ${this.$props.size}MB!`);
return false;
}
this.attachmentUploadFormData.append(this.$props.fileName, file);
this.pending = true;
return true;
},
handleOnUploadExceed() {
this.$message.error(`最多只能上传 ${this.$props.limit} 个附件~`);
},
async handleUploadHttpRequest() {
this.attachmentUploading = true;
return this.$props
.api(this.attachmentUploadFormData)
.then(response => Promise.resolve(response))
.catch(error => Promise.reject(error));
},
handlePreview(file) {
this.viewerUrl = file.url;
this.showViewer = true;
},
handleOnRemove(file, fileList) {
if (this.attachmentTooLarge) {
this.attachmentTooLarge = false;
return;
}
this.$emit("change", fileList);
}
}
};
</script>
<style lang="scss" scoped>
.uploader {
display: inline-block;
width: 100%;
&[exceed="true"] {
::v-deep {
.el-upload.el-upload--picture-card {
display: none;
}
}
}
::v-deep {
.el-list-enter-active,
.el-list-leave-active {
transition: unset;
}
.el-list-enter,
.el-list-leave-active {
opacity: 0;
transform: unset;
}
}
}
</style>