el-upload上传单张图片的时候,选中一张图片之后隐藏上传框

在el-form每个el-form-item在el-pload上传单张图片的时候,选中一张图片展示出图片之后隐藏上传框展示

img

img

引用new bing作答:
以下是一个示例代码,展示了如何使用 el-upload 实现在 el-form 中上传并预览单张图片后隐藏上传框的功能。

<template>
  <el-form ref="form" :model="form">
    <el-form-item label="图片上传">
      <el-upload
        ref="upload"
        class="upload-demo"
        :action="uploadUrl"
        :show-file-list="false"
        :on-success="handleSuccess"
        :before-upload="beforeUpload"
      >
        <el-button slot="trigger" size="small" type="primary">上传图片</el-button>
        <img v-if="imageUrl" :src="imageUrl" class="preview-image" />
        <el-input v-else class="upload-input" placeholder="请选择文件" readonly />
      </el-upload>
    </el-form-item>
  </el-form>
</template>

<script>
export default {
  data() {
    return {
      form: {
        file: null
      },
      imageUrl: null,
      uploadUrl: '/your/upload/url'
    };
  },
  methods: {
    beforeUpload(file) {
      const isJPG = file.type === 'image/jpeg';
      const isPNG = file.type === 'image/png';
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG && !isPNG) {
        this.$message.error('上传图片只能是 JPG 或 PNG 格式');
        return false;
      }

      if (!isLt2M) {
        this.$message.error('上传图片大小不能超过 2MB');
        return false;
      }

      return true;
    },
    handleSuccess(response, file) {
      this.imageUrl = URL.createObjectURL(file.raw);
      this.form.file = file.raw;
      this.$refs.upload.clearFiles();
    }
  }
};
</script>

<style scoped>
.preview-image {
  max-width: 200px;
  max-height: 200px;
  margin-top: 10px;
}
.upload-input {
  width: 200px;
  height: 32px;
  margin-top: 10px;
}
</style>

在这个示例代码中,el-upload 组件包含了一个按钮和一个预览图片的区域。当用户选择一个图片上传时,before-upload 方法会检查文件类型和大小是否符合要求,如果通过检查,则会调用 handleSuccess 方法处理上传成功后的响应。在 handleSuccess 方法中,我们通过 URL.createObjectURL 创建了一个预览图片的 URL,将这个 URL 赋值给 imageUrl 变量,并将上传成功的原始文件赋值给 form.file 变量。最后,我们调用 $refs.upload.clearFiles() 方法清除上传队列,隐藏上传框并展示预览图片。

示例代码中的 uploadUrl 变量应该替换为你自己的上传地址。另外,如果你需要在提交表单时一起上传这张图片,请确保在表单提交前将 form.file 一起提交。

以下内容部分参考ChatGPT模型:


可以在el-upload组件的change事件中添加一个判断,如果上传成功,则将上传框隐藏,展示上传成功后的图片。具体实现可以参考以下代码:

<template>
  <el-form>
    <el-form-item label="上传图片">
      <el-upload
        action="/upload"
        :show-file-list="false"
        :on-success="handleSuccess"
        :before-upload="beforeUpload"
        :file-list="fileList">
        <img v-if="imageUrl" :src="imageUrl" style="max-width: 100%">
        <el-button v-else>点击上传</el-button>
      </el-upload>
    </el-form-item>
  </el-form>
</template>

<script>
export default {
  data() {
    return {
      fileList: [],
      imageUrl: ''
    }
  },
  methods: {
    handleSuccess(response, file, fileList) {
      this.imageUrl = URL.createObjectURL(file.raw)
      this.fileList = fileList
    },
    beforeUpload(file) {
      // 隐藏上传框
      this.$nextTick(() => {
        const uploadBtn = document.querySelector('.el-upload__input')
        uploadBtn.style.display = 'none'
      })
    }
  }
}
</script>

在beforeUpload方法中,通过$nextTick方法确保上传按钮已经渲染完毕,然后获取上传按钮元素,将其display属性设置为none,实现隐藏上传框的效果。在handleSuccess方法中,将上传成功后的图片展示出来,同时更新fileList数组。


如果我的建议对您有帮助、请点击采纳、祝您生活愉快

提供一套自己封装的组件,支持拖拽上传,点击选择上传。
上传后可以移除或者再次上传。
上传组件:upload.vue

<style lang="scss" scoped>
:deep(.el-button.el-button--small) {
  width: 65px;
  left: 50% !important;
  margin-left: -32.5px !important;
}
.roshi-upload input[type="file"]{
  height: 0;
  width: 0;
  position: relative;
  top:-2000px;
  left:-2000px;
  visibility: hidden;
}
.roshi-uploadArea {
  width: 400px;
}
.roshi-uploadArea .imageButton {
  position: absolute;
  left: 38px;
}
.roshi-uploadArea .imageButton.delete {
  top: 40px;
  left: 42px;
  background-color: transparent;
  color: #fff;
  border-color: #fff;
}
.roshi-uploadArea .imageButton.again {
  top: 84px;
  margin-left: 0;
}
.roshi-uploadArea .imageButton.upload {
  top: 100px;
}
.roshi-wechat-site-uploadArea .left{
  position: relative;
}
.roshi-uploadArea .cover {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  background-color: rgba(0, 0, 0, 0.6);
  border-radius: 4px;
}
.roshi-uploadArea .roshi-loading {
  margin-top: 40px;
}
.roshi-uploadArea .left {
  position: relative;
  /* cursor: pointer; */
  width: 150px;
  height: 150px;
  border: 1px solid #e4e9f2;
  border-radius: 4px;
  background-color: #f7f9fc !important;
  /*background-size: 42px !important;*/
  text-align: center;
}
.roshi-uploadArea .left .leftText {
  position: relative;
  top: 64px;
  height: 17px;
  font-size: 12px;
  color: #a6aebc;
  line-height: 17px;
}
.roshi-uploadArea .right {
  vertical-align: bottom;
  padding-left: 20px;
}
.roshi-uploadArea .right p {
  font-size: 14px;
  color: #cccccc;
  line-height: 20px;
}
</style>

<template>
    <div class="roshi-upload" :id="uploadId">
        <!-- <div class="uploadArea">
            拖入上传
        </div> -->
        <div class="roshi-uploadArea fn0 w400 ib" :style="{ width: showTips ? '400px' : 'auto' }">
            <div @mouseover="showButtonsForLogo = true" @mouseout="showButtonsForLogo = false" class="left ib" v-if="imageUrl" :style="{ background: `url('${ossDomain}${imageUrl}') center center /contain no-repeat` }">
                <transition-group name="el-fade-in">
                    <div :key="1" v-show="showButtonsForLogo || uploading" class="cover"></div>
                    <roshi-loading :key="4" v-show="uploading && !multiple"></roshi-loading>
                    <el-button :key="2" size="small" v-show="showButtonsForLogo && showDelete" class="imageButton delete" @click="deleteFile">删除
                    </el-button>
                    <el-button :key="3" :style="{ top: showDelete ? '84px' : '62px' }" v-show="showButtonsForLogo" type="success" size="small" class="imageButton again" @click="openUploadingDialog">重新上传</el-button>
                </transition-group>
            </div>
            <div class="left ib" v-show="uploading && multiple">
                <div class="cover"></div>
                <roshi-loading></roshi-loading>
            </div>
            <div :id="dropAreaId" :style="{
                background: `url('${ossDomain}${ossAssets}upload/20221005/0znbos.png') center 34px /24px 24px no-repeat`,
                'border-color': dragIn ? '#0D55CF' : '#e4e9f2',
                'border-style': dragIn ? 'dashed' : 'solid'
            }" v-show="!imageUrl && !uploading" class="left ib waitUpload">
                <p class="leftText">可将本地{{ imgOrVideo }}拖拽到这里</p>
                <el-button size="small" type="success" class="imageButton upload" @click="openUploadingDialog">上传</el-button>
            </div>
            <div class="right ib" v-show="showTips">
                <p>格式要求:</p>
                <p>1、支持Jpeg、Jpg、Png格式</p>
                <p>2、大小不超过5M</p>
            </div>
        </div>
        <input @change="fileChange" type="file" name="file" :multiple=multiple />
    </div>
</template>

<script>
export default {
    name: "RoshiUpload",

};
</script>

<script setup>
import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue'
const loadUploadUtils = () => import('@/utils/upload.js');
const props = defineProps({
    imageUrl: {
        type: String, // 参数类型
        default: "", //默认值
        required: false, //是否必传
    },
    showTips: {
        type: Boolean,
        default: false
    },
    showDelete: {
        type: Boolean,
        default: true
    },
    accept: {
        type: String,
        default: '.jpg,.jpeg,.png,'
    },
    limitSize: {
        type: Number,
        default: 5
    },
    multiple : {
        type:Boolean,
        default:true
    },
    imgOrVideo:{
        type:String,
        default:'图片'
    }
})

const emits = defineEmits(['update:imageUrl', 'change'])
/* reactive data */
const uploadId = ref('fi' + window.app.$get32Id())
const dropAreaId = ref('da' + window.app.$get32Id())
const showButtonsForLogo = ref(true)
const uploading = ref(false)
// 是否放入
const dragIn = ref(false)
/* data */
/* methods */
// 此处定义一个drop容器(省略),并取到该元素;
function dragEnter(e) {
    e.stopPropagation();
    e.preventDefault();
    dragIn.value = true
}

function dragOver(e) {
    e.stopPropagation();
    e.preventDefault();
}

function dragleave(e) {
    e.stopPropagation();
    e.preventDefault();
    if (e.relatedTarget.id === uploadId.value) {
        dragIn.value = false
    }
}

function isChildOf(child, parent) {
    if (child && parent) {
        let parentNode = child.parentNode;
        while (parentNode) {
            if (parent === parentNode) {
                return true;
            }
            parentNode = parentNode.parentNode;
        }
    }
    return false;
}

function drop(e) {
    e.stopPropagation();
    e.preventDefault();
    if (!e.dataTransfer.files.length) {
        return
    }
    uploading.value = true
    dragIn.value = false
    // 当文件拖拽到dropBox区域时,可以在该事件取到files
    const files = e.dataTransfer.files;
    let file = files[0]
    let suffix = file.name.substr(file.name.lastIndexOf("."))
    if (props.accept.indexOf(suffix) < 0) {
        // window.app.$notify({message: '请上传.Jpeg,.Jpg,.Png类型的文件', type:'warning'})
        window.app.$tip.warning(`请上传 ${props.accept}类型的文件`)
        uploading.value = false
        return;
    }
    if (file.size > 1024 * 1024 * props.limitSize) {
        // window.app.$notify({message: '文件大小不能超过5M!', type:'warning'})
        window.app.$tip.warning(`文件大小不能超过${props.limitSize}M!`)
        uploading.value = false
        return
    }
    upload(file);
}

const openUploadingDialog = () => {
    if (uploading.value) {
        // window.app.$notify({message: '存在未完成上传的文件,请稍候', type:'warning'})
        window.app.$tip.warning('存在未完成上传的文件,请稍候')
        return
    }
    document.querySelector('#' + uploadId.value + ' input').value = "";
    document.querySelector('#' + uploadId.value + ' input').click();
}
const deleteFile = () => {
    emits('update:imageUrl',)
    emits('change')
    document.querySelector('#' + uploadId.value + ' input').value = "";
}
const fileChange = (e) => {
    uploading.value = true;
    let input = e.target;
    let files = e.target.files;
    if (files && files[0]) {
        let file = files[0]
        let suffix = file.name.substr(file.name.lastIndexOf("."))
        if (props.accept.indexOf(suffix.toLowerCase())< 0) {
            // window.app.$notify({message: '请上传.Jpeg,.Jpg,.Png类型的文件', type:'warning'})
            window.app.$tip.warning(`请上传${props.accept}类型的文件`)
            input.value = ''
            uploading.value = false
            return false;
        }
        if (file.size > 1024 * 1024 * props.limitSize) {
            // window.app.$notify({message: '文件大小不能超过5M!', type:'warning'})
            window.app.$tip.warning(`文件大小不能超过${props.limitSize}M!`)
            input.value = ''
            uploading.value = false
            return false
        }
        upload(file);
    }
}
const upload = (file) => {

    loadUploadUtils().then((res) => {
        res.uploadFile(file)
            .then((res) => {
                emits('update:imageUrl', res.url)
                emits('change', { ...res, file })
                uploading.value = false; console.log(res);
            })
            .catch((e) => {
                console.error(e);
            });
    });
}
onMounted(() => {
    nextTick(() => {
        const dropBox = document.querySelector('#' + dropAreaId.value);
        dropBox.addEventListener("dragenter", dragEnter, false);
        dropBox.addEventListener("dragover", dragOver, false);
        dropBox.addEventListener("dragleave", dragleave, false);
        dropBox.addEventListener("drop", drop, false);
    })
})
onBeforeUnmount(() => {
    const dropBox = document.querySelector('#' + dropAreaId.value);
    dropBox.removeEventListener("dragenter", dragEnter, false);
    dropBox.removeEventListener("dragover", dragOver, false);
    dropBox.removeEventListener("dragleave", dragleave, false);
    dropBox.removeEventListener("drop", drop, false);
})
defineExpose({
    openUploadingDialog
})
</script>


遮罩组件uploading:


<style lang="scss" scoped>
.loadEffect {
  //   width: 5em;
  //   height: 5em;
  position: relative;
  margin: 0 auto;
  // scale: 0.3428;
}
.loadEffect span {
  display: inline-block;
  //   width: 0.8em;
  //   height: 0.8em;
  border-radius: 50%;
  background: var(--el-color-primary);
  position: absolute;
  -webkit-animation: load 1.04s ease infinite;
}
@-webkit-keyframes load {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0.2;
  }
}
.loadEffect span:nth-child(1) {
  left: 0;
  top: 50%;
  //   margin-top: -0.4em;
  -webkit-animation-delay: 0.13s;
}
.loadEffect span:nth-child(2) {
  //   left: 0.7em;
  //   top: 0.7em;
  -webkit-animation-delay: 0.26s;
}
.loadEffect span:nth-child(3) {
  left: 50%;
  top: 0;
  //   margin-left: -0.4em;
  -webkit-animation-delay: 0.39s;
}
.loadEffect span:nth-child(4) {
  //   top: 0.7em;
  //   right: 0.7em;
  -webkit-animation-delay: 0.52s;
}
.loadEffect span:nth-child(5) {
  right: 0;
  top: 50%;
  //   margin-top: -0.4em;
  -webkit-animation-delay: 0.65s;
}
.loadEffect span:nth-child(6) {
  //   right: 0.7em;
  //   bottom: 0.7em;
  -webkit-animation-delay: 0.78s;
}
.loadEffect span:nth-child(7) {
  bottom: 0;
  left: 50%;
  //   margin-left: -0.4em;
  -webkit-animation-delay: 0.91s;
}
.loadEffect span:nth-child(8) {
  //   bottom: 0.7em;
  //   left: 0.7em;
  -webkit-animation-delay: 1.04s;
}
</style>

<template>
    <div class="roshi-loading">
        <div class="loadEffect" :style="{width: 5 * zoom + 'em', height: 5 * zoom + 'em'}">
            <span :style="{width: 0.8 * zoom + 'em', height: 0.8 * zoom + 'em','margin-top': -0.4 * zoom + 'em'}"></span>
            <span :style="{width: 0.8 * zoom + 'em', height: 0.8 * zoom + 'em', left: 0.7 * zoom + 'em', top: 0.7 * zoom + 'em'}"></span>
            <span :style="{width: 0.8 * zoom + 'em', height: 0.8 * zoom + 'em', 'margin-left': -0.4 * zoom + 'em'}"></span>
            <span :style="{width: 0.8 * zoom + 'em', height: 0.8 * zoom + 'em', right: 0.7 * zoom + 'em', top: 0.7 * zoom + 'em'}"></span>
            <span :style="{width: 0.8 * zoom + 'em', height: 0.8 * zoom + 'em', 'margin-top': -0.4 * zoom + 'em'}"></span>
            <span :style="{width: 0.8 * zoom + 'em', height: 0.8 * zoom + 'em', right: 0.7 * zoom + 'em', bottom: 0.7 * zoom + 'em'}"></span>
            <span :style="{width: 0.8 * zoom + 'em', height: 0.8 * zoom + 'em', 'margin-left': -0.4 * zoom + 'em'}"></span>
            <span :style="{width: 0.8 * zoom + 'em', height: 0.8 * zoom + 'em', left: 0.7 * zoom + 'em', bottom: 0.7 * zoom + 'em'}"></span>
        </div>
    </div>
</template>

<script>
export default {
    name: "RoshiLoading",
    props: {
        zoom: {
            type: Number,
            default: 1
        }
    }
};
</script>

<script setup>
</script>

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在vue中使用element-ui的el-upload上传单张图片,选中图片之后隐藏上传框可以通过以下步骤实现:

  1. 设置el-upload组件的show-file-list属性为false,这样选择完图片后不会显示上传框,只会显示已选中的图片。
  2. 在 el-upload 的change事件中获取上传完成后的图片,然后将其赋值给data里面的响应属性。
  3. 在el-form-item中展示图片,同时隐藏上传框。

具体的实现代码如下:

<template>
  <el-form>
    <el-form-item>
      <el-upload
        class="avatar-uploader"
        :show-file-list="false"
        :before-upload="beforeAvatarUpload"
        :action="uploadUrl"
        :on-success="handleAvatarSuccess"
        :on-error="handleAvatarError"
        :headers="{'Authorization': token}"
        :file-list="fileList"
        :auto-upload="false"
        ref="upload">
        <img v-if="imageUrl" :src="imageUrl" class="avatar">
        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
      </el-upload>
    </el-form-item>
  </el-form>
</template>

<script>
  export default {
    data() {
      return {
        fileList: [],
        imageUrl: ''
      }
    },
    methods: {
      beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/jpeg'
        if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG 格式!')
        }
        return isJPG
      },
      handleAvatarSuccess(res, file) {
        this.imageUrl = URL.createObjectURL(file.raw)
        this.fileList.push(file)
        this.$refs.upload.clearFiles() // 上传完毕后清空文件列表,隐藏上传框
      },
      handleAvatarError() {
        this.$message.error('上传头像图片失败!')
      }
    }
  }
</script>

<style scoped>
  .avatar-uploader {
    display: inline-block;
    width: 100px;
    height: 100px;
    text-align: center;
    line-height: 100px;
    border-radius: 50%;
    border: 1px solid #d9d9d9;
    background-color: #f7f7f7;
    overflow: hidden;
  }
  .avatar {
    width: 100%;
    height: 100%;
    display: block;
  }
  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    cursor: pointer;
    transition: color .3s;
  }
  .avatar-uploader-icon:hover {
    color: #409EFF;
  }
</style>

以上代码中,el-upload组件的show-file-list属性设置为false,beforeAvatarUpload用来限制上传的图片类型,handleAvatarSuccess处理上传成功的图片,handleAvatarError处理上传失败的情况,imageUrl用来保存上传后的图片地址。同时,我们给 el-upload 绑定了 ref,方便在上传完成后清空文件列表,隐藏上传框。

在 el-form-item 中,我们通过判断是否有 imageUrl 展示图片,如果有则展示图片,否则展示上传图标。由于之前我们已经将上传框隐藏,所以上传图标只会在一开始出现,之后选择图片后就不会再出现了。
如果我的回答解决了您的问题,请采纳!