美文网首页
element-ui上传组件

element-ui上传组件

作者: 吞风咽雪 | 来源:发表于2020-11-25 14:23 被阅读0次

组件代码

<template>
  <div>
    <co-upload
      ref="upload"
      class="image-edit"
      name="file"
      :show-file-list="showFileList"
      :list-type="listType"
      :file-list="fileList"
      :action="action"
      :data="data"
      :limit="limit"
      :before-upload="handleBeforeUpload"
      :on-success="handleUploadSuccess"
      :on-error="handleUploadError"
      :on-progress="handleProgress"
      :on-change="handleChange"
      :on-preview="handlePictureCardPreview"
      :on-remove="handleRemove"
    >
      <slot>
        <!-- <el-button size="small" type="primary">点击上传</el-button> -->
        <i class="co-icon-add" />
      </slot>
      <co-progress v-if="status==='uploading'" :percentage="progress" />
      <slot name="tip">
        <p slot="tip" class="tip">
          <span v-if="rules.width||rules.height" class="tip-item">{{ `宽高限制:${rules.width}x${rules.height} ` }}</span>
          <span v-if="rules.fileSize" class="tip-item">{{ `大小限制:${fileSizeParse} ` }}</span>
          <span v-if="rules.extensions" class="tip-item">{{ `格式限制:${rules.extensions} ` }}</span>
        </p>
      </slot>
    </co-upload>
    <co-dialog :visible.sync="dialogVisible">
      <img class="img-preview" :src="dialogImageUrl" alt="">
    </co-dialog>
  </div>
</template>
<script>
/**
 * <upload :before-upload="beforeUpload" @success="uploadSuccess" :rules="{width:200,height:100,fileSize:100,extensions:'jpg,png'}"/>
 */
export default {
  props: {
    action: {
      type: String,
      default() {
        return this.GLOBAL_SETTINGS.uploadApi
      }
    },
    showFileList: {
      type: Boolean,
      default: false
    },
    listType: {
      type: String,
      default: 'text'
    },
    fileList: {
      type: Array,
      default() {
        return []
      }
    },
    data: {
      type: Object,
      default() {
        return {
          type: 'appDomain'
        }
      }
    },
    limit: {
      type: Number,
      default: undefined
    },
    beforeUpload: {
      type: Function,
      default() {
        return () => { return true }
      }
    },
    rules: {
      type: Object,
      default() {
        return {
          width: 0, // 图片宽
          height: 0, // 图片高
          fileSize: 0, // 文件大小 B
          extensions: ''// 文件后缀 'jpg,png,gif'
        }
      }
    }

  },
  data() {
    return {
      status: 'ready',
      progress: 0,
      dialogImageUrl: '',
      dialogVisible: false
    }
  },
  computed: {
    PATH() {
      return `${process.env.VUE_APP_BASE_API}/music/cms/musiccms/upload/`
    },
    // 自动识别文件大小单位
    fileSizeParse() {
      const fileSize = this.rules.fileSize
      if (fileSize < 1024) {
        return fileSize + 'B'
      } else if (fileSize < 1024 * 1024) {
        return parseInt(fileSize / 1024) + 'K'
      } else if (fileSize < 1024 * 1024 * 1024) {
        return parseInt(fileSize / 1024 / 1024) + 'M'
      } else {
        return parseInt(fileSize / 1024 / 1024 / 1024) + 'G'
      }
    }
  },
  methods: {
    // 限制符合宽高
    isSize(file) {
      return new Promise((resolve, reject) => {
        if (this.rules.width || this.rules.height) {
          // 当width和height同时为 0 时不验证
          const img = new Image()
          var _URL = window.URL || window.webkitURL
          img.onload = () => {
            if (
              img.width !== this.rules.width ||
              img.height !== this.rules.height
            ) {
              this.$message.error(
                `上传的图片尺寸只能是${this.rules.width}x${this.rules.height}`
              )
              reject('不符合宽高')
            } else {
              resolve('符合宽高')
            }
          }
          img.src = _URL.createObjectURL(file)
        } else {
          resolve('无宽高限制')
        }
      })
    },
    // 限制文件大小
    isByte(file) {
      const isByte = !this.rules.fileSize ? true : file.size <= this.rules.fileSize // 文件大小符合
      if (!isByte) {
        this.$message.error(`上传文件大小不能超过 ${this.fileSizeParse}!`)
      }
      return isByte
    },
    // 限制文件格式
    isExtensions(file) {
      const extensions = this.rules.extensions
      if (!extensions) {
        return true
      } else {
        const pattern = extensions.replace(/,/g, '$|\\.').replace(/\*/g, '.*') + '$'
        const regexp = new RegExp(pattern, 'i')
        const invalid = regexp.test(file.name)
        if (!invalid) {
          this.$message.error(`文件类型限制: ${this.rules.extensions}`)
        }
        return invalid
      }
    },
    // 上传前
    handleBeforeUpload(file) {
      console.log(12312)
      return new Promise((resolve, reject) => {
        const Fns = [
          this.isSize(file),
          this.isByte(file),
          this.isExtensions(file),
          this.beforeUpload(file)
        ]
        Promise.all(Fns).then(res => {
          if (res.includes(false)) {
            reject()
          } else {
            resolve()
          }
        }).catch(err => {
          console.log('err', err)
          reject()
        })
      })
    },
    clearFiles() {
      this.$refs['upload'].clearFiles()
    },
    // 上传成功
    handleUploadSuccess(res, file, fileList) {
      console.log(file)
      if (res.errno === 0) {
        this.$emit('success', res, file, fileList)
      } else {
        this.$message.error(res.data.message)
      }
      // this.clearFiles()
    },
    // 上传失败
    handleUploadError(err, file, fileList) {
      this.$message.error(err)
      this.clearFiles()
    },
    // 文件上传时的钩子
    handleProgress(event, file, fileList) {
      this.status = 'uploading'
      this.progress = Math.round(event.percent)
    },
    // 文件状态改变时的钩子
    handleChange(file, fileList) {
      this.status = file.status
    },
    // 预览
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    // 移除
    handleRemove(file, fileList) {
      this.$emit('remove', file, fileList)
    }
  }
}
</script>
<style lang="scss" scoped>
.tip{
  color: #999999;
  font-size: 12px;
  margin: 0;
  &-item{
   margin-right: 12px;
  }
}
.img-preview{
  max-width: 100%;
  margin: auto;
  display: block;
}

</style>
<style lang="scss">
.image-edit{
  .el-upload-list__item {
    .el-upload-list__item-name {
      display: block;
      color: #ffffff;
      background: rgba(0, 0, 0, 0.3);
      position: absolute;
      bottom: 0;
      width: 100%;
      text-align: center;
      .el-icon-document {
        display: none;
      }
    }
  }
}
</style>

相关文章

网友评论

      本文标题:element-ui上传组件

      本文链接:https://www.haomeiwen.com/subject/jclniktx.html