element-ui实现证件照上传预览下载组件封装
效果:
参数说明
我只写了两个参数,后续有需求再对其组件进行丰富~
参数 | 说明 |
---|---|
fileListProp | 用来存储上传后后端返回的图片UR了 |
uploadUrl | 图片上传反悔的URL后端接口地址 |
父组件调用:
<au-upload :uploadUrl="'http://192.168.60.27:8888/file-storage-center/object/uploadObjectByMultipartFile'" :fileListProp="fileList1">
</au-upload>
<p><span>*</span> <span class="idCardTip">身份证国徽面</span></p>
组件源码:
<template>
<div>
<el-upload v-loading="loading" element-loading-text="上传中..." :style="{ 'width': width + 'px', 'height': height + 'px' }" class="avatar-uploader"
:class="noneBtnDealImg ? 'disUoloadSty' : ''" ref="uploader"
:file-list="fileList"
:action="uploadUrl"
:before-upload="beforeUpload"
:on-exceed="(files, fileList) => handleExceed(files, fileList, 1)"
:on-change="(file, fileList) => this.handleAvatarSuccess(file, fileList)"
list-type="picture-card"
:auto-upload="true">
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{file}">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
<span class="el-upload-list__item-actions">
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleDownload(file)">
<i class="el-icon-download"></i>
</span>
<span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
import axios from 'axios'; // 导入axios
export default {
props: {
fileListProp: {
typeof: Array,
default: () => []
},
uploadUrl: {
typeof: String,
default: () => ''
},
},
data() {
return {
width: 140,
height: 140,
fileList: this.fileListProp,
headerObj: {
authorization: getToken(),
tenant_id: 0,
},
img: '',
noneBtnDealImg: false,
uploadfileurl: this.uploadFileURL,
dialogImageUrl: '',
dialogVisible: false,
disabled: false,
loading: false,
};
},
created() {
},
mounted() {
this.noneBtnDealImg = this.fileList.length >= 1
},
methods: {
beforeUpload(file) {
// 检查文件类型、大小等
const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPGorPNG) {
this.$message.error('上传的图片只能是 JPG 或 PNG 格式!');
return false;
}
if (!isLt2M) {
this.$message.error('上传的图片大小不能超过 2MB!');
return false;
}
// 发起上传请求
this.directUpload(file);
// 返回false阻止el-upload组件的默认上传行为
return false;
},
async directUpload(file) {
try {
this.loading = true
const formData = new FormData();
formData.append('file', file);
const response = await axios.post(this.uploadUrl, formData, {
headers: this.headerObj,
});
// 处理上传成功
this.handleUploadResponse(response.data, file);
} catch (error) {
// 处理上传错误
console.error('Upload error:', error);
} finally {
this.loading = false;
}
},
handleUploadResponse(responseData, file) {
// 根据后端返回的数据,更新fileList
const updatedFile = {
...file,
response: responseData,
url: responseData.data || '', // 假设后端返回的URL在这里
};
this.fileList.push(updatedFile);
//当前只保留一张照片
this.$nextTick(() => {
if (this.fileList.length >= 1) {
const uploadBox1 = document.getElementsByClassName('avatar-uploader');
uploadBox1[0].style.height = this.height + "px"
}
this.noneBtnDealImg = this.fileList.length >= 1
})
},
//图片删除
handleRemove(file, fileList, name) {
const index = this.fileList.indexOf(file);
if (index > -1) {
this.fileList.splice(index, 1);
}
this.img = ''
this.noneBtnDealImg = this.fileList.length >= 1
this.$refs['uploader'].clearFiles();
this.$forceUpdate()
},
handleExceed(files, fileList, num) {
this.$message.warning(`当前限制选择 ${num} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
handleAvatarSuccess(file, fileList) {
this.$nextTick(() => {
if (fileList.length >= 1) {
const uploadBox1 = document.getElementsByClassName('avatar-uploader');
uploadBox1[0].style.height = this.height + "px"
}
this.noneBtnDealImg = fileList.length >= 1
})
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handleDownload(file) {
// 获取图片的真实URL
const imageUrl = file.response && file.response.data ? file.response.data : file.url;
// 创建一个隐藏的可下载链接
const link = document.createElement('a');
link.style.display = 'none';
link.href = imageUrl;
link.download = file.name || 'image.png'; // 设置下载的文件名,如果没有name属性则默认为'image.png'
// 触发点击事件以下载图片
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
</script>
<style scoped>
.el-form-item__label::after {
content: '(最多1张)';
display: block;
font-size: 12px;
color: #999;
line-height: 12px;
}
/deep/ .allUpload .el-form-item__content {
display: flex;
}
/deep/ .el-upload-list__item {
transition: none !important
}
/deep/ .disUoloadSty .el-upload--picture-card {
/* 上传按钮隐藏 */
display: none !important;
}
/deep/ .el-upload--picture-card {
width: 140px;
height: 140px;
}
/deep/ .el-upload-list--picture-card .el-upload-list__item {
margin-right: 0px !important;
margin-bottom: 0px !important;
}
/deep/ .el-upload-list__item {
width: 140px !important;
height: 140px !important;
}
/deep/ .el-upload-list__item div:nth-child(1) {
width: 100% !important;
height: 100% !important;
}
/deep/ .el-loading-spinner .el-loading-text{
text-align: center;
margin-top: -18px;
}
</style>