<template>
<div>
<el-upload ref="uploadEl" :style="disabled ? { pointerEvents: 'none' } : ''"
:class="isBtnUpload ? '' : 'uploader'" action="" :multiple="multiple" :limit="limit" :file-list="fileList"
:list-type="listType" :accept="accept" :show-file-list="showFileList" :on-change="handleUploadChange"
:on-remove="handleRemove" :before-remove="beforeRemove" :on-exceed="handleExceed"
:http-request="function () { }" :disabled="disabled">
<template v-if="!isBtnUpload">
<div v-if="localValue && !showFileList" class="show-box">
<img v-if="localValue" style="width: 146px; height: 146px; border-radius: 5px; vertical-align: top"
class="el-upload-list__item-thumbnail" :src="localValue" />
<i v-else class="el-icon-document" style="font-size: 68px" />
<div v-if="!defaultConfig.disabled" class="thumb_action">
<span>{{ defaultConfig.text ? '重新' + defaultConfig.text : '重新上传' }}</span>
<span v-if="localValue && showDelBtn" class="del" @click.stop="onRemove">删除</span>
</div>
</div>
<div v-if="!localValue || showFileList" class="slot-default">
<i class="el-icon-plus" />
<p class="co-text-gray" :style="defaultConfig.textStyles">
<i v-show="defaultConfig.loading" class="el-icon-loading co-font-18"
style="vertical-align: middle" />
{{ defaultConfig.text || '点击上传' }}
</p>
</div>
</template>
<template v-else>
<el-button size="small" type="primary">点击上传</el-button>
</template>
</el-upload>
</div>
</template>
<script>
export default {
name: "ProUpload",
props: {
disabled: {
type: Boolean,
default: false
},
isBtnUpload: {
type: Boolean,
default: false
},
showDelBtn: {
type: Boolean,
default: false
},
text: {
type: Boolean,
default: false
},
tip: {
type: String,
default: ""
},
multiple: {
type: Boolean,
default: false
},
limit: {
type: Number,
default: 1
},
listType: {
type: String,
default: ""
},
showFileList: {
type: Boolean,
default: false
},
maxSize: {
type: Number,
default: 10
},
accept: {
type: String,
default: ".jpg,.png,.jpeg"
},
noPreview: {
type: Boolean,
default: false
},
fileList: {
type: Array,
default: () => []
},
value: {
type: [File, String],
default() {
return null
}
}
},
data() {
return {
localValue: this.value || null,
file: "",
defaultConfig: {
loading: false,
accept: ".jpg,.png,.jpeg",
limit: 1,
multiple: false,
tips: ""
}
}
},
computed: {
upAccept() {
return this.accept.toLocaleUpperCase()
},
formatAccept() {
const up = this.accept.toLocaleUpperCase()
const lower = this.accept.toLocaleLowerCase()
return up + "," + lower
}
},
watch: {
value: {
handler(val) {
this.localValue = val
},
deep: true,
immediate: true
},
localValue: {
handler(val) {
if ((!val || !val.length) && !this.showFileList) {
this.$refs.uploadEl?.clearFiles()
}
},
deep: true,
immediate: true
}
},
mounted() {
this.resetLocalValue()
},
methods: {
resetLocalValue() {
this.$refs.uploadEl?.clearFiles();
},
onRemove() {
this.$confirm("确定删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.localValue = null
this.$emit("onRemoveCallback")
}).catch(() => { });
},
handlePreview() {
},
handleExceed(files, fileList) {
if (this.showFileList) this.$message.warning(`当前限制上传${this.limit}个文件,如需上传新的文件,请先删除上传过的文件`);
},
beforeRemove(file, fileList) {
return this.$confirm(`确定删除 ${file.name}?`);
},
handleRemove(file, fileList) {
this.$emit("callback", { type: "remove", file: fileList })
},
handleDownload() {
this.$emit("callback", { type: "download" })
},
handleUploadChange(file, fileList) {
console.log("文件改变", file, fileList)
const name = file.name
const isLimit = file.size / 1024 / 1024 > this.maxSize
this.resetLocalValue()
if (isLimit) {
const uid = file.uid
const idx = fileList.findIndex(item => item.uid === uid)
fileList.splice(idx, 1)
this.$message.error(`上传文件大小不能超过 ${this.maxSize}MB!`)
return
}
const postfix = name.substring(name.lastIndexOf("."))
if (this.accept && !this.accept.includes(postfix)) {
const uid = file.uid
const idx = fileList.findIndex(item => item.uid === uid)
fileList.splice(idx, 1)
this.$message.error(`只能上传${this.accept}文件!`)
return
}
const imgType = ".jpg,.png,.jpeg"
if (imgType.includes(postfix)) {
this.localValue = URL.createObjectURL(file.raw)
} else {
this.localValue = ""
}
this.file = file
this.$emit("callback", { type: "upload", file: file.raw })
}
}
}
</script>
<style lang="scss" scoped>
.hide_box {
::v-deep .el-upload.el-upload--picture-card,
::v-deep .el-upload.el-upload--picture {
display: none;
}
}
.show-box {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 148px;
.thumb_action {
position: absolute;
top: 0;
left: 0;
width: 148px;
height: 148px;
z-index: 12;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
opacity: 0;
transition: opacity 0.15s;
display: flex;
flex-direction: column;
justify-content: space-between;
border-radius: 5px;
.del {
margin: 0 auto;
&:hover {
opacity: 0.8;
}
}
}
&:hover {
.thumb_action {
opacity: 1;
}
}
}
.slot-default {
line-height: normal;
width: 148px;
height: 148px;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.uploader {
::v-deep .el-upload {
border: 1px dashed #c0ccda;
border-radius: 5px;
}
}
</style>