Vue+element圖片上傳

前言:使用element上傳圖片以後,文件file下的url是blob:http//localhost:8080地址,後端很差處理css

問題如上圖所示html

採用比較笨的js解決方法,將bolb文件打開,讀取src屬性(這是一個base64的數據流),把src的內容一塊兒發送給後端。node

這是一個上傳圖片子組件demoajax

<template>
  <el-upload class="upload-demo" action="" ref="upload" :auto-upload='false' :on-change='changeUpload' accept="image/jpeg,image/gif,image/png,image/bmp">
    <div size="small" class="upload_btn"><div style="height:40px"></div><i class="iconfont icon-jiahao"></i><p style="line-height:0">點擊上傳</p></div>
  </el-upload>
</template>
<script>
export default {
  name: 'regShopImg',
  data () {
    return {
      imageUrl: '',
      imgthing: {}
    }
  },
  props: ['imgN', 'nameN'],
  methods: {
    changeUpload (file, fileList) {
      console.log(file)
      // 判斷圖片大小
      if (fileList[0].size < 1100000) {
        // 判斷圖片格式是否爲jpg,png,jepg,gif
        var fileName=fileList[0].name
        // var suffixIndex=fileName.lastIndexOf(".")
        // var suffix=fileName.substring(suffixIndex+1).toUpperCase()
        var suffix = fileName.substring(fileName.lastIndexOf(".")+1).toUpperCase()
        if (suffix=="BMP"||suffix=="JPG"||suffix=="JPEG"||suffix=="PNG"||suffix=="GIF") {
            this.fileList = fileList
            this.$nextTick(
            () => {
              var i = this.imgN
              let uploadLists = document.getElementsByClassName('el-upload-list')
              let uploadListsN = uploadLists[i]
              let uploadListLi = uploadListsN.children
              uploadListsN.setAttribute('style', 'position: absolute;height: 160px;margin-top: 0;margin-left: 300px;width: 260px;overflow: hidden')
              let liA = uploadListLi[0]
              // 試着獲取bolb裏面的數據------------S
              //獲取圖片的Blob值
              function getImageBlob(url, cb) {
                  var xhr          = new XMLHttpRequest()
                  xhr.open("get", url, true)
                  xhr.responseType = "blob"
                  xhr.onload       = function() {
                      if (this.status == 200) {
                          if(cb) cb(this.response)
                      }
                  }
                  xhr.send()
              }
              function preView(url){
                  let reader    = new FileReader()
                  getImageBlob(url, function(blob){
                      reader.readAsDataURL(blob)
                  })
                  reader.onload = function(e) {
                      // 獲取bolb裏面數據時,生成預覽
                      var img = document.createElement("img")
                      img.src = e.target.result
                      // 獲取bolb裏面數據時,生成預覽
                      let imgElement = document.createElement('img')
                      imgElement.setAttribute('src', fileList[0].url)
                      imgElement.setAttribute('style', 'max-width:100%;padding-left:0')
                      if (liA.lastElementChild.nodeName !== 'IMG') {
                        liA.appendChild(imgElement)
                      }
                      // 把base64的信息放到imgthing的file裏
                      file.base64 = e.target.result
                  }
              }
              preView(fileList[0].url)
              // 試着獲取bolb裏面的數據-------------E
              // 不獲取bolb裏面數據時,生成預覽
              // let imgElement = document.createElement('img')
              // imgElement.setAttribute('src', fileList[0].url)
              // imgElement.setAttribute('style', 'max-width:100%;padding-left:0')
              // if (liA.lastElementChild.nodeName !== 'IMG') {
              //   liA.appendChild(imgElement)
              // }
            }
          )
          // 修改nameN名字對應的數據,在一個頁面使用多個不一樣字段圖片上傳,爲了複用組件
          if (this.nameN === 'identityCard_Z') {
            this.imgthing.identityCard_Z = file
          }
          if (this.nameN === 'identityCard_F') {
            this.imgthing.identityCard_F = file
          }
          if (this.nameN === 'identityCard_S') {
            this.imgthing.identityCard_S = file
          }
          this.$emit('imgthing', this.imgthing)
        } else {
          this.$message.error('文件類型不正確,請從新上傳!')
        }
      } else {
        this.$message.error('圖片大小超過1M,請從新上傳')
      }
    }
  }
}
</script>

<style scoped lang="scss">
// 上傳
  .upload-demo{width:260px;height:160px;
    .upload_btn{width:260px;height:160px;background:#f2f2f2}
    .el-upload__tip{margin:0;float:left}
  }
</style>

父組件上傳demo後端

<template>
<!-- 表單信息 -->
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
  <!-- 第三步-提交資質內容 -->
  <div v-if="this.active === 3">
    <el-form-item label="身份證號碼" prop="identityCard">
      <el-input type="identity" v-model="ruleForm.identityCard" style="width:260px" placeholder="請輸入身份證號"></el-input>
    </el-form-item>
    <el-form-item label="身份證正面" prop="identityCard_Z">
      <RegShopImg :imgN='0' :nameN='identityCard_Z' @imgthing = 'imgthing' v-model="ruleForm.identityCard_Z"></RegShopImg>
    </el-form-item>
    <el-form-item label="身份證反面" prop="identityCard_F">
      <RegShopImg :imgN='1' :nameN='identityCard_F' @imgthing = 'imgthing' v-model="ruleForm.identityCard_F"></RegShopImg>
    </el-form-item>
    <el-form-item label="手持身份證" prop="identityCard_S">
      <RegShopImg :imgN='2' :nameN='identityCard_S' @imgthing = 'imgthing' v-model="ruleForm.identityCard_S"></RegShopImg>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm('ruleForm')" class="btn_submit">提 交 資 質</el-button>
    </el-form-item>
  </div>
</el-form>
</template>

<script>
import RegShopImg from '@/components/common/regShopImg' //上傳圖片的子組件
import Qs from 'qs' // post方式下引入qs插件字符串化傳輸信息
export default {
  name: 'regShop',
  data () {
    return {
      active: 3, // 分步驟走的斷定
      ajaxRegisterUrl: '', // 註冊提交頁面
      imgN: '', // 上傳信息的名字對應的index序號
      nameN: '', // 上傳信息的名字
      identityCard_Z: 'identityCard_Z',
      identityCard_F: 'identityCard_F',
      identityCard_S: 'identityCard_S',
      Imgthing: {}, //子組件上傳的信息
      ruleForm: { // 提交信息的表單對象
        identityCard_Z: '',
        identityCard_F: '',
        identityCard_S: '',
      },
      rules: { // 必填斷定規則
        identityCard_Z: [
          {required: true, message: '請上傳身份證正面圖片', trigger: 'blur'}
        ],
        identityCard_F: [
          {required: true, message: '請上傳身份證反面圖片', trigger: 'blur'}
        ],
        identityCard_S: [
          {required: true, message: '請上傳手持身份證圖片', trigger: 'blur'}
        ]
      }
    }
  },
  methods: {
    // 第三步:證件照片上傳
    imgthing (imgthing) {
      // 合併對象
      this.Imgthing = Object.assign(this.Imgthing, imgthing)
      // 填充到ruleForm對應項,用來判斷是否有數據
      this.ruleForm.identityCard_Z = this.Imgthing.identityCard_Z
      this.ruleForm.identityCard_F = this.Imgthing.identityCard_F
      this.ruleForm.identityCard_S = this.Imgthing.identityCard_S
    },
    // 總表單提交
    submitForm (formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          // 因爲base64的數據流比較大,get方式放不下,必須採用post方式
          let data = Qs.stringify(this.ruleForm)
          this.$ajax.post(this.ajaxRegisterUrl, data)
            .then((res) => {
              console.log(res)
              if (res.status === 1) {
                this.$message.success('恭喜您,註冊成功!')
              }
            })
        } else {
          this.$message.error('提交資料有誤,註冊失敗!')
          return false
        }
      })
    }
  },
  components: {
    'RegShopImg': RegShopImg
  }
}
</script>
<style scoped lang="scss">
</style>

多添加了一個base64的數據app

另外一種思路是利用element已有的方式,將圖片上傳和表單上傳分開。ide

圖片上傳只上傳文件,利用上傳成功handleAvatarSuccess(res, file)的方法,獲取後端對上傳圖片存儲位置的路徑,並將其傳給父組件。提交表單的時候,提交圖片部分僅僅是路徑。post

參考文檔:

1.js 獲取圖片url的Blob值並預覽:https://www.cnblogs.com/tujia/p/6483255.html ui

相關文章
相關標籤/搜索