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 = trueconst 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) {// 根据后端返回的数据,更新fileListconst 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 >= 1this.$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) {// 获取图片的真实URLconst 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>