elementui新增或修改时,el-upload上传组件回显预览删除(el-upload上传图片base64给后端)

15 篇文章 0 订阅
文章介绍了如何在Vue.js应用中创建一个公共的子组件用于图片上传,支持预览和删除功能。图片以Base64字符串形式与后端交互。子组件通过props接收数据并回显,同时通过事件触发向父组件传递上传后的图片URL。父组件可以根据不同字段调用子组件并区分图片。
摘要由CSDN通过智能技术生成

实现功能:

     addOrUpdate.vue新增或修改时,修改需要可以回显图片,上传图片后要可以预览以及删除。

     当页面有多个字段涉及上传单图的,也可以使用子组件作为公共的组件引入。

     这里前后端关于图片的交互都是base64字符串,所以回显和上传提交的也都是base64字符串。

图片:

el-upload照片墙只上传一张,隐藏另一张参考的是如下链接:
        https://blog.csdn.net/weixin_59395272/article/details/128649347

 上传预览实现效果图如下:

父组件

     多个字段需要用到这个公共的上传组件,加type字段进行区分(示例是父组件页面多字段上传图片)。

     如果只有一个字段上传图片,也是可以用子组件的,一个字段的话就不用加判断

      getChildParam 和 getUploadChildData修改为更简单的直接赋值。

  注意点:

 <div v-if="showUpload"> showUpload默认设置为true,保证每次子组件都进一次mounted方法

关键示例代码如下:

 <el-form-item label="正面照" >
         <div v-if="showUpload">
           <upload-child ref="imgUpload1" :data="getChildParam('1','正面照')" @getUploadChildData="getUploadChildData"></upload-child>
        </div>
        </el-form-item>


      <el-form-item label="背面照" >
        <div v-if="showUpload">
          <upload-child ref="imgUpload1" :data="getChildParam('2','背面照')" @getUploadChildData="getUploadChildData"></upload-child>
        </div>
      </el-form-item>


      <el-form-item label="侧面照" >
        <div v-if="showUpload">
          <upload-child ref="imgUpload1" :data="getChildParam('3','侧面照')" @getUploadChildData="getUploadChildData"></upload-child>
        </div>
        </el-form-item>


// 传给子组件的数据 ,用于子组件回显和区分
getChildParam(type,title){
	var obj = new Object();
	obj.type = type;
	obj.title = title;
	obj.fileList =[];
	
	switch(type){
		case '1':
			obj.fileList = this.frontImgList; // 获取详细信息的时候赋值frontImgList 主要是为了回显
		break;
		case '2':
			obj.fileList = this.backImgList;
		break;
		case '3':
			obj.fileList = this.sideImgList;
		break;
	
	}
	return obj;

},

//接收子组件上传的base64格式的图片url,赋值给想传给后端的对象
getUploadChildData(obj){
	switch(obj.type){
		case '1':
			this.frontImgUrl = obj.url;  
		break;
		case '2':
			this.backImgUrl = obj.url;  
		break;
		case '3':
			this.sideImgUrl = obj.url;  
		break;
	
	}

}

子组件

el-upload照片墙只上传一张,隐藏另一张参考如下链接:
        https://blog.csdn.net/weixin_59395272/article/details/128649347

    这是抽取一个公共的上传组件,同一个页面或不同页面(有一个或多个字段需要上传图片,但是字段都只需要上传一张图片)需要上传的时候可以引入这个公共的上传组件。

注意点:

      mounted 和hideAnother 解决的是页面正常回显了后端返回的图片,然后隐藏另一个多余的上传框,如果页面不涉及回显的话可以忽略这两个方法的处理。

      setTimeOut要加,避免还获取不到页面元素。


<template>
	<div>
	
	<el-upload action="#" 
		accept="image/**" :limit="1" :multiple="false" :auto-upload="false"
		list-type="picture-card" 
		:on-preview="(file)=>handleImgPreview(file,data.type)"
		:on-change="(file)=>changeUpload(file,data.type)"
		:file-list="data.fileList" 
		:before-upload="(file)=>handleBeforeUpload(file,data.type)"
		:on-exceed="handleExceed"
		:on-remove="(file)=>imgRemove(file,data.type)"
		:show-file-list="true"
        :class="type">
		
		<i class="el-icon-plus"></i>
	</el-upload>
	
  
	
	<el-dialog :visible.sync="imgVisible" :append-to-body="true" style="width:80%;height:100%;" :title="data.title">
		<div style="width:80%;height:80%;justify-content:center;align-items:center;text-align:center;display:flex">
                <div v-viewer>
                     <img :src="imgUrl"  style="height: 200px; width: 200px; " />
                </div>
        </div>
	</el-dialog>
 

	</div>
 </template>
 
 
 <script>
 
 import  {getBase64Url} from '@/api/utils.js'
 
 export default {
	name:"upload",
	props:{
        data:{
            type: Object,
            default:()=>{return {} }
        },
    },
    
	data(){
		return {
			fileList:[],
            imageList:[],
			hideUpload:false,
			imgVisible:false,
			imgUrl:'',
			onChangeImgUrl:'',
            type:'',
		}
	},
    mounted(){
        //有数据 回显隐藏 多余upload   如果只是新增可以不考虑
        setTimeout(()=>{
             //通过动态加样式,使上传组件唯一,方便隐藏多余的上传框
            this.type="type"+this.data.type;//动态设置class值
            var length = this.data.fileList.length;
            if(length>=1){
                this.hideAnother();
            }

        },20)
       
    },
	//监听事件
	watch: {
     data:{
            handler(newData) {
                 //通过动态加样式,使上传组件唯一,方便隐藏多余的上传框
                this.type="type"+newData.type;//动态设置class值
                var length = newData.fileList.length;
                if(length>=1){
                    this.hideAnother();
                }

            },deep:true
        },
	  //只上传一张图片,照片墙隐藏多余的上传框
	  onChangeImgUrl: {
		handler(newName) {
           //这个type上传后,隐藏这个多余的上传框,
           //这个type代表上传的该字段标识,该字段上传隐藏该字段多余框
		  var aa = document.querySelector('.'+this.type+' .el-upload--picture-card');
            //document.querySelector('.el-upload--picture-card')
		  if (newName) {
			aa.style.display = 'none' 
		  } else {
			setTimeout(() => {
			  aa.style.display = 'inline-block'
			}, 1100)
		  }
		}
	  }
	 
	},
	methods:{
        hideAnother(){
            //要加setTimeOut避免此时元素还找不到 为null
            setTimeout(()=>{
                var aa = document.querySelector('.'+this.type+' .el-upload--picture-card');
                aa.style.display = 'none' 
            },20)
        },
		//上传基本校验
		handleBeforeUpload(file,type){
			var img = file.name.substring(file.name.lastIndexOf('.') + 1)
			const suffix = img === 'jpg'
			const suffix2 = img === 'png'
			const suffix3 = img === 'jpeg'
			const isLt1M = file.size / 1024 / 1024 < 1;
			if (!suffix && !suffix2 && !suffix3) {
				this.$message.error("只能上传图片!");
				return false
			}
			// 可以限制图片的大小
			if (!isLt1M) {
				this.$message.error('上传图片大小不能超过 1MB!');
			}
			return suffix || suffix2 || suffix3
		},
		// 弹窗 图片预览
		handleImgPreview(file,type){
			this.imgUrl = file.url;
            this.imageList.push(file.url);
			this.imgVisible = true;
            // this.$refs.preview.dispatchEvent(new MouseEvent('click'));

		},
		//上传后 删除
		imgRemove(file ,type){
			this.onChangeImgUrl = '';
			var parentObj = new Object ();
			parentObj.type = type ;
			parentObj.url = '';// 传给父组件方法
			this.$emit("getUploadchildData", parentObj);
		},
		//上传超出提示
		handleExceed(files,filelist){
			this.$message.error("上传图片不能超过1张!");
		},
		//上传控件的改变事件 提交到父组件
		async changeUpload(file, type){
			this.onChangeImgUrl = file.url;
			
			//图片转base64
			const response = await getBase64Url(file)
			var res = response.result
			
			var parentObj = new Object ();
			parentObj.type = type ;
			parentObj.url = res;// 传给父组件方法
			this.$emit("getUploadchildData", parentObj);
		}
	
	}
}
 </script>

 <style  >
 .img{
    width: 60%;
    height: 80;
    margin: 0 auto;
    display: flex;
    justify-content: center;
    align-items: center;
 }
 </style>

util.js图片转base64

// 转base64  el-upload上传的file 不能直接用,要用file.raw
// 文件对象转base64
export  function getBase64Url (file) {
	return  new Promise ((resolve,reject) =>{
			  const reader = new FileReader(); //实例化文件读取对象
			  reader.readAsDataURL(file.raw); //将文件读取为 DataURL,也就是base64编码
			 reader.onload = function () {
				resolve(reader)
			 }
			 reader.onerror = function (error) {
				reject(error)
			 }
	
	})
   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值