自定義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 = ''實現。

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