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的图片,不需要在做其他的处理
相关推荐
轻口味1 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王1 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发2 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀2 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef4 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
sunshine6414 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻5 小时前
Vue(四)
前端·javascript·vue.js
蜜獾云5 小时前
npm淘宝镜像
前端·npm·node.js