el-upload 上传图片转成base64 字符串,传给后端,且base64在页面的展示

1.dragUpdate 文件上传组件

​
<template>
  <el-upload
    ref="uploadRef"
    action="#"
    v-bind="$attrs"
    drag
    :accept="accept"
    :auto-upload="false"
    :show-file-list='isNotLogo'
    :on-change="handleUploadChange"
    :on-remove="handleUploadRemove"
    :on-exceed="onExceed"
    :class="[isNotLogo ? 'drag-upload': 'logo-upload']"
  >
    <div v-if='isNotLogo' class="el-upload__text">
      <d2-icon-svg :name="icon" />
      <h6>点击或将文件拖拽到这里上传</h6>
      <p v-if="illustrate ">{{ illustrate }}</p>
    </div>
    <div>
      <h6>点击或将文件拖拽到这里上传</h6>
      <p>{{`支持扩展名:${accept}`}}</p>
    </div>
  </el-upload>
</template>

<script>
export default {
  name: 'DragUpdate',
  props: {
    accept: {
      type: String,
      default: ''
    },
    // 文件大小限制,单位为M
    fileSize: {
      type: Number,
      default: 20
    },
    value: {
      type: [Array, Object],
      default: null
    },
    icon: {
      type: String,
      default: 'drag-upload'
    },
    isNotLogo: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      file: null,
      fileName: ''
    }
  },
  computed: {
    illustrate() {
      const { accept, fileSize, $attrs } = this
      const info = [
        `支持扩展名:${accept}`,
        `单个文件最大支持${fileSize}Mb`
      ]
      if ($attrs.limit) info.push(`最多可选${$attrs.limit}个文件`)
      return info.join(',')
    }
  },
  methods: {
    handleFileValidate(file, fileList) {
      const accept = this.accept.split(',')
      const size = this.fileSize * 1024 * 1024
      const name = file.name
      const format = name.substring(name.lastIndexOf('.'), name.length)
      if (!accept.some((val) => val === format)) {
        this.$message.error(`不支持 ${format} 格式的文件`)
        this.$refs.uploadRef.handleRemove(file)
        return false
      }
      if (file.size > size) {
        this.$message.error(`文件大小不能超过${this.fileSize}Mb`)
        this.$refs.uploadRef.handleRemove(file)
        return false
      }

      if (fileList.filter(item => item.name === file.name).length > 1) {
        this.$message.error(`"${file.name}"文件名重复'`)
        this.$refs.uploadRef.handleRemove(file)
        return false
      }

      return true
    },
    handleUploadChange(file, fileList) {
      if (!this.handleFileValidate(file, fileList)) return
      this.setValue(fileList)
    },
    handleUploadRemove(file, fileList) {
      this.setValue(fileList)
    },
    onExceed(files, fileList) {
      // 文件个数超出限制
      const { limit } = this.$attrs
      const len = files.length
      const olen = fileList.length
      if (limit && len + olen > limit) {
        const msg = `当前已选择${olen}个文件,还可选择${limit - olen}个文件`
        this.$message.error(olen ? msg : `最多可选${limit}个文件`)
      }
    },
    setValue(fileList) {
      fileList.forEach(item => {
        item.isUpload = true
      })
      const { limit } = this.$refs.uploadRef
      this.file = [...fileList]
      if (limit === 1) this.file = fileList.length ? fileList[0] : null
      this.fileName = fileList.map(item => item.name).join(',')
      this.$emit('input', this.file)
      this.$emit('change', { file: this.file, fileName: this.fileName })
    }
  }
}
</script>

<style lang="scss" scoped>
.drag-upload {
  max-width: 600px;
  ::v-deep {
    .el-upload-dragger {
      width: 600px;
      height: 192px;
      border-color: rgba(0,0,0,0.15);
      border-radius: 8px;
      &:hover {
        border-color: var(--theme-color, #409EFF);
      }
      svg {
        margin-top: 50px;
        font-size: 40px;
      }
      h6 {
        margin: 14px 0 4px;
        font-size: 16px;
        font-weight: 400;
        color: #262626;
        line-height: 24px;
      }
      p {
        font-size: 14px;
        color: #8C8C8C;
        line-height: 22px;
        padding: 0 10px;
      }
    }
    .el-upload-list__item {
      &:first-child {
        margin-top: 0;
      }
      &-name {
        color: #595959;
      }
    }
  }
}
.theme-tech {
  .drag-upload {
    ::v-deep {
      .el-upload-dragger {
        border-color: rgba(0, 225, 228, 0.4);
        background-color: rgba(59, 139, 255, 0.1);
        &:hover {
          border-color: rgba(0, 225, 228, 1);
        }
        h6 {
          color: #fff;
        }
        p {
          color: #BFD9FF;
        }
        svg {
          color: #fff;
        }
      }
      .el-upload-list__item {
        &-name {
          color: #00AEFF;
        }
      }
    }
  }
}

.logo-upload {
  ::v-deep{
    .el-upload-dragger {
      width: auto;
      height: auto;
      padding: 0px 10px;
    }
  }
}
</style>

​

2.使用

<dragUpdate v-model="file" :key='num'   :disabled="logoUrl !== ''|| imageUrl !== ''" accept=".jpg,.jpeg,.png,.gif" :isNotLogo='false' :file-size="50" :limit="1" @change="fileChange"></dragUpdate>
         

 <div class='logo-info' v-if='imageUrl'>
            <el-image :src="imageUrl" class='logo-img'></el-image>
            <div class='logo-delete' @click='delLogo'>
              <d2-icon-svg name="cancel" />
            </div>
          </div>


fileChange(fileInfo) {
      this.file = fileInfo
      let that = this;
      let file = fileInfo.file.raw;
      // this.imageUrl = URL.createObjectURL(file);
      var reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onloadend = function(){
        // 将文件(file)转换成base64字符串
        that.imageUrl = reader.result;
      }
    },

 

3.base64 数据的展示

解释:el-image组件能直接展示base64的图片,不需要在做其他的处理

在使用 `el-upload` 组件时,如果希望将后端返回的 base64 字符串回显为已上传的文件,需要对 base64 数据进行处理,并模拟成一个包含 `url` 和 `id` 的文件对象数组。以下是实现方法和注意事项: ### 处理 base64 数据并回显 在详情页中,当获取到后端返回的 base64 格式的图片数据时,可以将其封装为一个包含 `id` 和 `url` 的对象,并赋值给 `el-upload` 的 `file-list` 属性。具体操作如下: ```javascript this.$refs.addModal.fileList = [ { id: Number(Math.random() * 100), // 生成一个随机ID url: res.result.licensePic // 后端返回的base64字符串 } ]; ``` 通过这种方式,`el-upload` 组件会将 base64 字符串识别为已上传的文件,并在界面上展示对应的图片预览。 ### 将 base64 换为文件对象 在某些场景下,可能需要将 base64 字符串换为 `File` 对象以便进一步处理。可以通过以下函数实现: ```javascript function base64ToFile(base64, filename, mimeType) { const byteString = atob(base64.split(',')[1]); const ab = new ArrayBuffer(byteString.length); const ia = new Uint8Array(ab); for (let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } const blob = new Blob([ab], { type: mimeType }); return new File([blob], filename, { type: mimeType }); } ``` 调用该函数后,可以得到一个 `File` 对象,便于后续操作(如重新上传、修改等)。 ### 注意事项 - **Base64 数据格式**:确保后端返回的 base64 数据是完整的,通常以 `data:image/png;base64,...` 开头。 - **文件大小限制**:base64 数据可能会占用较大的内存,需注意页面性能问题。 - **兼容性**:不同浏览器对 base64 的支持略有差异,建议测试主流浏览器的表现[^1]。 ### 示例代码 以下是一个完整的示例,展示如何将 base64 字符串回显到 `el-upload` 组件中: ```html <template> <el-upload action="https://jsonplaceholder.typicode.com/posts/" :file-list="fileList" list-type="picture-card" :on-preview="handlePreview" :on-remove="handleRemove"> <i class="el-icon-plus"></i> </el-upload> </template> <script> export default { data() { return { fileList: [] }; }, mounted() { // 模拟从后端获取base64数据 const base64Image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...'; // 示例base64数据 this.fileList = [ { id: 1, url: base64Image } ]; }, methods: { handlePreview(file) { console.log('预览文件:', file); }, handleRemove(file, fileList) { console.log('移除文件:', file, fileList); } } }; </script> ``` 通过上述方法,可以轻松地将 base64 字符串回显为已上传文件,同时保持与 `el-upload` 组件的良好兼容性。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值