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

1.dragUpdate 文件上传组件

javascript 复制代码
​
<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.使用

javascript 复制代码
<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 数据的展示

bash 复制代码
解释:el-image组件能直接展示base64的图片,不需要在做其他的处理
相关推荐
musk12124 分钟前
electron 打包太大 试试 tauri , tauri 安装打包demo
前端·electron·tauri
翻滚吧键盘33 分钟前
js代码09
开发语言·javascript·ecmascript
万少1 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
OpenGL1 小时前
Android targetSdkVersion升级至35(Android15)相关问题
前端
rzl021 小时前
java web5(黑马)
java·开发语言·前端
Amy.Wang1 小时前
前端如何实现电子签名
前端·javascript·html5
海天胜景1 小时前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui
今天又在摸鱼1 小时前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js
蓝婷儿2 小时前
每天一个前端小知识 Day 21 - 浏览器兼容性与 Polyfill 策略
前端
百锦再2 小时前
Vue中对象赋值问题:对象引用被保留,仅部分属性被覆盖
前端·javascript·vue.js·vue·web·reactive·ref