el-upload图片增删改和到达最大上传数后隐藏随后上传栏封装组件

开始用el-upload,发现:file-list绑定的只是用来预览,并不是双向绑定(此处没有时间再继续深入研究)。

自己写了一个el-upload组件,用于多图片的增删改,最终返回promise对象,方便表单提交前用PromiseAll检查多个该组件全部上传成功后提交表单。

抛砖引玉欢迎大家指点(其实我还没怎么测)。

<template>
  <div>
    <el-upload
      ref="imgUpload"
      class="upload-img"
      action=""
      :class="{hide:hideUploadEdit}"
      list-type="picture-card"
      :on-remove="handleRemove"
      :on-change="handleChange"
      :auto-upload="false"
      accept=".png, .jpg"
      :limit="limit"
      :on-exceed="handleExceed"
      :multiple="true"
      :file-list="previewObject"
    >
      <i class="el-icon-plus" />
      <div slot="tip" class="el-upload__tip">{{ $t('product.SPCImgDrawUploadTip') }}</div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>
<script>
import * as _ from 'lodash'
import axios from 'axios'
import { getToken } from '@/utils/auth'

export default {
  name: 'ImgEditUpload',
  props: {
    // 要上传的链接
    url: {
      type: String,
      required: true
    },
    // 限制文件数
    limit: {
      type: Number,
      default: 1
    },
    // 图片预览拼接字符串,以"|"分割
    previewUrlStr: {
      type: String,
      default: ''
    },
    // 最大文件大小:5M
    maxFileSize: {
      type: Number,
      default: 5
    }
  },
  data() {
    return {
      // 预览图片dialog开关
      dialogVisible: false,
      // 预览对象,用于显示已有文件
      previewObject: [],
      // 预览对象用于显示已有文件备份,用于重置后恢复
      previewObjectBack: [],
      // 是否到达最大文件,隐藏后面的上传栏
      hideUploadEdit: false,
      // 已上传文件数组
      haveUploadedFileList: [],
      // 预览图片dialog url
      dialogImageUrl: ''
    }
  },
  mounted() {
    this.initUploadFileFormat()
  },
  methods: {
    // 初始化文件格式
    initUploadFileFormat() {
      if (this.previewUrlStr === null || this.previewUrlStr === '') {
        this.previewObject = []
      } else {
        const imgUrlStrArr = this.previewUrlStr.split('|')
        const imgObjectArr = []
        for (const urlStr of imgUrlStrArr) {
          const tempImgObject = {}
          // 未展示文件名,此处以后应使用正则
          tempImgObject['name'] = 'test'
          tempImgObject['url'] = urlStr
          imgObjectArr.push(tempImgObject)
        }
        this.previewObject = imgObjectArr
        // 防止出现过多的上传组件
        this.hideUploadEdit = (imgObjectArr.length >= this.limit)
        // 备份一份用于重置
        this.previewObjectBack = _.cloneDeep(this.previewObject)
      }
    },
    // The hook function of add product draw upload file
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    // The number of uploads exceeded the limit
    handleExceed() {
      this.$message.error(`目前最多只支持${this.limit}个`)
    },
    // THe hook function of remove product img upload file
    handleRemove(file, fileList) {
      this.haveUploadedFileList = fileList
      this.hideUploadEdit = fileList.length >= this.limit
    },
    handleChange(file, fileList) {
      this.haveUploadedFileList = fileList
      this.hideUploadEdit = (fileList.length >= this.limit)
    },
    // Check the size of file and the type of file before the upload file
    checkFile(fileRaw) {
      const isJPG = fileRaw.type === 'image/jpeg' || fileRaw.type === 'image/png'
      const isLt2M = fileRaw.size / 1024 / 1024 < this.maxFileSize
      if (!isJPG) {
        this.$message.error('上传图片只能是 JPG 或 PNG 格式!')
        return false
      }
      if (!isLt2M) {
        this.$message.error(`上传图片大小不能超过${this.maxFileSize}MB!`)
        return false
      }
      return isJPG && isLt2M
    },
    customSubmit() {
      if (this.haveUploadedFileList.length !== 0) {
        // 有上传的新文件,或者删除过上传过的文件
        // 已经上传过的文件
        const previewUrlArr = []
        // 需要上传的文件raw
        const needUploadUrlRawArr = []
        for (const file of this.haveUploadedFileList) {
          if (file['status'] === 'success') {
            previewUrlArr.push(file['url'])
            continue
          }
          // 检查文件失败
          if (!this.checkFile(file.raw)) {
            return false
          } else {
            // 加入需要上传数组
            needUploadUrlRawArr.push(file.raw)
          }
        }
        // 如果有新文件就上传
        if (needUploadUrlRawArr.length !== 0) {
          const formData = new FormData()
          for (const raw of needUploadUrlRawArr) {
            formData.append('fileList', raw)
          }
          return new Promise((resolve, reject) => {
            axios({
              url: this.url,
              method: 'post',
              data: formData,
              headers: { 'Content-Type': 'multipart/form-data', 'X-Token': getToken() }
            }).then(res => {
              if (res.data.success === true) {
                // 预览的图片和上传后的图片url数组返回
                resolve({ type: 2, urlArr: [...previewUrlArr, ...(res.data.data.url)] })
              } else {
                reject(res.data.message)
              }
            })
          })
        } else {
          // 没有新文件上传
          return new Promise((resolve) => {
            resolve({ type: 1, urlArr: [...previewUrlArr] })
          })
        }
      } else if (this.haveUploadedFileList.length !== 0 && this.$refs.imgUpload.uploadFiles.length !== 0) {
        // 没有修改过已预览图片
        return new Promise((resolve) => {
          resolve({ type: 0, urlArr: [] })
        })
      } else if ((this.haveUploadedFileList.length === 0 && this.$refs.imgUpload.uploadFiles.length === 0)) {
        // 清空了所有图片
        return new Promise((resolve) => {
          resolve({ type: 3, urlArr: [] })
        })
      }
    }
  }
}
</script>
<style scoped lang="scss">
// 隐藏上传按钮
::v-deep .hide .el-upload--picture-card {
  display: none;
}

// 添加/删除文件时去掉动画过渡
::v-deep .el-upload-list__item {
  transition: none !important;
}
</style>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值