自定义input文件上传样式,并且解决两次选择同一个文件不触发change事件的方法

// tempelate
<div v-show="showImgBtn" class="upload-wrap">
<el-button size="small" @click="handleUploadCLick">选择图片<input ref="fileBtn" class="upload_input" type="file" accept="image/jpg, image/jpeg, image/png" @change="uploadImg"/></el-button>
</div>

// methods
async uploadImg() {
      try {
        var that = this
        that.imgSrcs = [] // 上传文件前清空。
        const inputFiles = await this.$refs.fileBtn.files
        if (this.$refs.fileBtn.files.length > 1) {
          // 最多只能上传1张图片
          return false
        }
        let fileList = []
        fileList = fileList.concat(Array.from(inputFiles)) // 将选择的文件列表对象变成数组
        let typeflag = false // 检测文件类型
        let sizeFlag = false // 检测文件大小
        const fileMaxSize = 500 * 1000 // 4M
        fileList.forEach(v => {
          if (
            v.type !== 'image/jpeg' &&
            v.type !== 'image/png' &&
            v.type !== 'image/jpg'
          ) {
            typeflag = true
          }
          if (v.size > fileMaxSize) {
            sizeFlag = true
          }
        })
        if (typeflag) {
          this.$message({
            message: this.$t('workOrder.uploadTypeTips'), // 不是有效的图片文件
            type: 'warning'
          })
          return false
        }
        if (sizeFlag) {
          this.$message({
            message: '图片大小不能超过500KB', // 文件大小不能超过4M
            type: 'warning'
          })
          return false
        }
        fileList.map(async v => {
          const res = await this.reviewFile(v)
          that.imgSrc = res
          that.imgSrcs.push(res)
        })
        // 必须情况input的value属性,不然第二次选择同样的文件,不会触发change事件。
        this.$refs['fileBtn'].value = ''
      } catch (error) {
        console.log(error)
      }
    },

// css
.upload-wrap {
    display: inline-block;
    text-align: center;
    cursor: pointer;
    outline: 0;
    position: relative;
  }
  .upload_input {
    display: inline-block;
    position: absolute;
    width: 80px;
    left: 0;
    top: 8px;
    opacity: 0;
  }

原理就是将input的透明度隐藏,点击按钮的时候,实际上也点击了input

另外一种方式是,给一个按钮绑定点击事件,在事件处理函数里去调用input的点击事件, vue中使用this.$refs['fileBtn'].click()也会触发input的点击事件,input的样式可用隐藏或透明。

注意:当两次选择的是同一个文件的时候,input的change事件不会触发,必须在合适的时机,将input的value属性设置为空。参考代码示例。在vue中可用使用this.$refs['fileBtn'].value = ''实现。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章