当前位置: 首页 > news >正文

vue2+element-UI上传图片封装

针对上传组件进行封装,在页面直接引用即可,上传到minio文件服务器:
可以预览,重新上传,只读模式,可以传入展示缩略图尺寸,传入上传校验尺寸

<template><div><div v-if="readOnly"class="avatar-uploader":style="{ width: width + 'px', height: height + 'px' }"><div v-if="imageUrl"class="image-container"@click.stop><img:src="`${baseUrl}/file/file/previewByCode/${imageUrl}`"class="avatar":style="{ width: width + 'px', height: height + 'px' }"><divclass="icon-wrapper":class="{ readonly: readOnly }"><spanclass="icon-item preview"@click="handlePreview"><el-tooltip content="查看"placement="top"effect="dark"><el-button type="primary"size="mini"style="margin-right: 0px; border: none; background: transparent;"class="el-icon-zoom-in"></el-button></el-tooltip></span></div></div><i v-elseclass="el-icon-plus avatar-uploader-icon"></i></div><el-upload v-elseclass="avatar-uploader":action="action":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload":style="{ width: width + 'px', height: height + 'px' }"><div v-if="imageUrl"class="image-container"@click.stop><img:src="`${baseUrl}/file/file/previewByCode/${imageUrl}`"class="avatar":style="{ width: width + 'px', height: height + 'px' }"><divclass="icon-wrapper":class="{ readonly: readOnly }"><spanclass="icon-item preview"@click="handlePreview"><el-tooltip content="查看"placement="top"effect="dark"><el-button type="primary"size="mini"style="margin-right: 0px; border: none; background: transparent;"class="el-icon-zoom-in"></el-button></el-tooltip></span><spanclass="icon-item reupload"@click="handleReUpload"><el-tooltip content="重新上传"placement="top"effect="dark"><el-button type="primary"size="mini"class="el-icon-upload"></el-button></el-tooltip></span><!--删除按钮:默认隐藏,父组件控制--><span v-if="showDelete"class="icon-item delete"@click="handleDelete"><el-tooltip content="删除"placement="top"effect="dark"><el-button type="primary"size="mini"class="el-icon-delete"></el-button></el-tooltip></span></div></div><i v-elseclass="el-icon-plus avatar-uploader-icon":style="{ width: width + 'px', height: height + 'px' }"></i></el-upload><el-image ref="imageRef"style="display: none;":src="`${baseUrl}/file/file/previewByCode/${imageUrl}`":preview-src-list="[`${baseUrl}/file/file/previewByCode/${imageUrl}`]"fit="cover"/></div></template><script>exportdefault{name:"ImageUpload",data(){return{baseUrl:this.$global.baseUrl,};},props:{imageUrl:{type:String,default:""},action:{type:String,default:''},width:{type:[String,Number],default:178},height:{type:[String,Number],default:178},readOnly:{type:Boolean,default:false},maxWidth:{type:Number,default:null},maxHeight:{type:Number,default:null},// 控制删除按钮显示,默认不展示showDelete:{type:Boolean,default:false}},methods:{handleAvatarSuccess(res,file){constdata=res.data||res;letimageUrl='';if(typeofdata==='string'){imageUrl=data;}elseif(data.url){imageUrl=data.url;}this.$emit('upload-success',data);},beforeAvatarUpload(file){constisJPG=file.type==='image/jpeg'||file.type==='image/png'||file.type==='image/gif'||file.type==='image/bmp';constisLt2M=file.size/1024/1024<10;if(!isJPG){this.$message.error('上传图片只能是 JPG、PNG、GIF、BMP 格式!');returnfalse;}if(!isLt2M){this.$message.error('上传图片大小不能超过 10MB!');returnfalse;}// ====================== 关键修改:判断是否需要校验尺寸 ======================// 如果四个尺寸属性都没传 → 不校验尺寸,直接通过constneedCheckSize=this.maxWidth!==null||this.maxHeight!==null||this.width!==178||this.height!==178;if(!needCheckSize){returntrue;}// 图片尺寸校验returnnewPromise((resolve,reject)=>{constreader=newFileReader();reader.onload=(e)=>{constimg=newImage();img.onload=()=>{const{width,height}=img;letisValid=true;leterrorMessage='';// 如果上传尺寸校验的props不存在,使用展示尺寸作为默认值consteffectiveMaxWidth=this.maxWidth!==null?this.maxWidth:this.width;consteffectiveMaxHeight=this.maxHeight!==null?this.maxHeight:this.height;if(width!==effectiveMaxWidth||height!==effectiveMaxHeight){errorMessage=`仅支持上传png/jpg/jpeg文件,上传尺寸为${effectiveMaxWidth}px*${effectiveMaxHeight}px`;isValid=false;}if(!isValid){this.$message.error(errorMessage);reject(newError(errorMessage));}else{resolve(true);}};img.src=e.target.result;};reader.readAsDataURL(file);});},// 原生预览,无任何依赖handlePreview(){if(!this.imageUrl)return;// 3. 获取组件实例 -> DOM -> 找到内部 img -> 触发点击// const imageComponent = this.$refs.imageRef// if (imageComponent) {// const imgElement = imageComponent.$el.querySelector('img')// if (imgElement) {// imgElement.click()// }// }// 直接调用 el-image 组件的公共方法this.$refs.imageRef.clickHandler();},handleReUpload(){if(this.readOnly)return;constuploadInput=this.$el.querySelector('.el-upload__input');if(uploadInput){uploadInput.click();}},// 删除图片:内部清空,向父组件传递空字符串handleDelete(){if(this.readOnly)return;this.$confirm('确定删除该图片?','提示',{confirmButtonText:'确定',cancelButtonText:'取消',type:'warning'}).then(()=>{// 直接向父组件抛出空值,父组件绑定的 imageUrl 自动清空this.$emit('upload-success','');}).catch(()=>{});}}};</script><style scoped>.avatar-uploader{border:none;border-radius:6px;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;background:#f5f7fa;}.avatar-uploader:hover{cursor:pointer;}.image-container.icon-wrapper{position:absolute;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center;gap:20px;opacity:0;transition:opacity0.3s;z-index:10;}.image-container:hover.icon-wrapper{opacity:1;}.image-container.icon-wrapper.readonly{opacity:1;background:transparent;justify-content:center;}.image-container.icon-wrapper.readonly.icon-item{background:rgba(0,0,0,0.4);}.icon-item{width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;color:#fff;cursor:pointer;font-size:16px;transition:all0.2s;}.icon-item:hover{background:#409EFF;transform:scale(1.1);}/* 按钮样式 */.icon-item.el-button{border:none;border-radius:50%;width:32px;height:32px;padding:0;display:flex;align-items:center;justify-content:center;background:transparent!important;color:#fff!important;box-shadow:none!important;}.icon-item.el-button:hover,.icon-item.el-button:focus{background:transparent!important;color:#fff!important;box-shadow:none!important;}.image-container{position:relative;width:100%;height:100%;display:flex;align-items:center;justify-content:center;overflow:hidden;}.avatar-uploader img{width:100%;height:100%;object-fit:cover;cursor:default;}.avatar-uploader.el-upload{width:100%;height:100%;display:flex;align-items:center;justify-content:center;}.avatar-uploader-icon{font-size:28px;color:#8c939d;display:flex;align-items:center;justify-content:center;width:100%;height:100%;}.avatar{display:block;}</style><style>/* 强制隐藏图片预览底部的那个“全屏”图标 *//* 这里直接锁定类名包含 'el-icon-full-screen' 的图标 *//* .el-image-viewer__actions .el-icon-full-screen { display: none !important; } */</style>

图片:

引用方式:

<el-form-item prop="douyinQrcode"label="抖音二维码"><image-upload v-model="douyinQrcode":image-url="douyinQrcode":width="90":height="90":action="baseUrl + '/file/file/upload/banner'"@upload-success="handleDouyinQrcodeSuccess"></image-upload><pclass="hint">仅支持上传png/jpg/jpeg文件,上传尺寸为90*90px,图片大小不超过10M</p></el-form-item>

*注:

preview-src-list:1、图片 宽/高 ≤ 屏幕:按原尺寸居中显示,不放大2、图片 宽/>屏幕:1)展示图片原尺寸2)缩小图片比例,缩放到刚好放进屏幕,保证完整可见
http://www.jsqmd.com/news/711943/

相关文章:

  • AI时代程序员真的会被替代吗_一份冷静的岗位分析报告
  • 告别卡顿!WaveTools鸣潮工具箱让你的游戏体验丝滑如新
  • 新手程序员必看:用RAG技术为AI大模型配置知识库,轻松提升能力并收藏!
  • 从 15V 交流到 5V 直流:桥式整流、电容滤波与 LM7805 稳压电源设计解析
  • 盟接之桥®制造业EDI软件:从Forecast到Invoice,打通供应链的“任督二脉”
  • 扩散模型与轨迹规划:提升生成式AI效率与质量
  • 【Python编程-03】从零入门 Python 加密算法!含完整可运行代码 + 场景对比 + 避坑详解
  • 【多线路故障】含sop的配电网故障重构研究(Matlab代码实现)
  • StitchFlow:基于AI的本地化UI原型生成工作流实践
  • 第十七届蓝桥杯省赛c++b组题解
  • 高通X105调制解调器:5G Advanced与6G关键技术解析
  • 如何用GHelper轻松掌控华硕笔记本性能:5分钟快速配置终极指南
  • 整个 AI 项目从本地 → 部署到服务器
  • 工业级Cat-1导轨式DTU USR-DR154/DR152(口红DTU)技术规范、核心优势与标准化应用场景白皮书
  • 被低估的 .NET 开源项目:AngleSharp,优雅的 HTML 解析神器
  • 10 分钟让网页颜值翻倍(底层+手写+AI提示词)
  • MySQL如何防止通过权限提升攻击_严格控制SUPER权限分配范围
  • 5分钟极速部署NVIDIA Riva ASR语音识别服务
  • YOLO26桥梁缺陷识别检测系统(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+远程环境部署)
  • 初步了解安卓逆向
  • 2026甘肃亮化工程权威TOP5排行:兰州亮化工程/兰州亮化设计/兰州体育场亮化/兰州体育场泛光照明/兰州商业综合体亮化/选择指南 - 优质品牌商家
  • NDCG@k:推荐系统排序质量评估的核心指标
  • 苹果MacBook Neo与保时捷968 Club Sport:如何让便宜产品变酷炫,成市场新宠?
  • 2026年合肥留学机构测评,最好的口碑好中介如何选 - 速递信息
  • 宜宾宅心装饰2026技术解析:口碑背后的工艺与服务细节 - 优质品牌商家
  • YOLO26电梯内电动车识别检测系统(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+远程环境部署)
  • Portarium:轻量级本地服务可视化管理的Go语言实现
  • 2026年武汉留学中介机构前十解析,哪家科研服务口碑最好 - 速递信息
  • 2026年3月回收运动木地板品牌推荐,二手运动体育木地板回收/回收运动木地板,回收运动木地板服务联系电话 - 品牌推荐师
  • AI编程助手技术对比与实战应用指南