elementui が追加または変更されると、el-upload アップロード コンポーネントはプレビューをエコーして削除します (el-upload はイメージ Base64 をバックエンドにアップロードします)。

機能を実現します。

     addOrUpdate.vue が追加または変更される場合、その変更は画像をエコーできる必要があり、アップロードされた画像はプレビューおよび削除できる必要があります。

     ページにアップロードされたシート画像に関連する複数のフィールドがある場合、サブコンポーネントをパブリック コンポーネントとして導入することもできます。

     ここで、画像のフロントエンドとバックエンド間の対話はbase64文字列であるため、エコーとアップロード送信もbase64文字列です。

写真:

el-upload フォト ウォールは 1 つだけアップロードします。もう 1 つの参照は次のリンクです:
        https://blog.csdn.net/weixin_59395272/article/details/128649347

 アップロードプレビューの効果図は以下のとおりです。

親コンポーネント

     複数のフィールドでこの共通のアップロード コンポーネントを使用する必要があり、区別するためにタイプ フィールドが追加されます (例として、親コンポーネント ページのマルチフィールド アップロード画像)。

     写真をアップロードするフィールドが 1 つだけの場合は、サブコンポーネントも使用できます。フィールドが 1 つであれば、判断する必要はありません

      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 フォト ウォールは 1 つだけをアップロードし、もう 1 つは非表示にします。次のリンクを参照してください:
        https://blog.csdn.net/weixin_59395272/article/details/128649347

    これはパブリック アップロード コンポーネントを抽出するためのもので、アップロードが必要な場合、同じページまたは異なるページ (1 つ以上のフィールドで写真をアップロードする必要がありますが、すべてのフィールドで 1 つの写真のみをアップロードする必要があります) でこのパブリック アップロード コンポーネントを導入できます。

注意点:

      Mounted と HideAnother は、通常、ページがバックエンドから返された画像をエコーし​​、別の冗長なアップロード ボックスを非表示にするという問題を解決します。ページにエコーが含まれていない場合、これら 2 つのメソッドの処理は無視できます。

      ページ要素を取得できないことを避けるために、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)
			 }
	
	})
   
}

おすすめ

転載: blog.csdn.net/ss_Tina/article/details/130237726