码仔ROC 2023-11-09 17:23 采纳率: 50%
浏览 17
已结题

vue+ant-design-vue中的a-upload上传文件

使用a-upload上传文件,需要对文件坐判断,
但是beforeupload方法还没走完,action上传方法就同步在上传了。@change方法也在同时进行

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-11-10 05:03
    关注

    【相关推荐】



    • 这篇文章讲的很详细,请看:ant-design-vue文件上传中的beforeUpload方法和change方法
    • 您还可以看一下 张代浩老师的ant-design-vue UI组件使用讲解课程中的 upload小节, 巩固相关知识点
    • 除此之外, 这篇博客: Vue中图片上传组件封装-antd的a-upload二次封装-案例中的 组件封装 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
      <template>
        <div class="upbase">
          <!-- 进度条-->
          <div v-show="progressVisible" class="progress-container">
            <div class="progress-bar"></div>
          </div>
          <a-upload
            v-if="!uploadType"
            :beforeUpload="beforeImageUpload"
            list-type="picture-card"
            :file-list="imageList"
            :multiple="multiple"
            :disabled="disabled"
            @change="handleImageChange"
            @preview="handlePreview"
            :custom-request="customRequest"
          >
            <div v-if="imageList.length < limitNum && !disabled">
              <a-icon type="plus" />
              <div class="ant-upload-text">上传</div>
            </div>
          </a-upload>
      
          <a-upload
            v-else
            name="file"
            :file-list="imageList"
            :beforeUpload="beforeImageUpload"
            :multiple="multiple"
            :disabled="disabled"
            :custom-request="customRequest"
            @change="handleImageChange"
          >
            <!-- list-type="picture" -->
            <div v-if="imageList.length < limitNum && !disabled">
              <a-button> <a-icon type="upload" /> 上传 </a-button>
            </div>
          </a-upload>
      
          <!-- 图片预览 -->
          <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
            <img alt="example" style="width: 100%" :src="previewImage" />
          </a-modal>
        </div>
      </template>
      
      <script>
      import { UploadImage, DeleteImage } from '@/api/public'
      
      function getBase64(file) {
        return new Promise((resolve, reject) => {
          const reader = new FileReader()
          reader.readAsDataURL(file)
          reader.onload = () => resolve(reader.result)
          reader.onerror = (error) => reject(error)
        })
      }
      
      function getName(url) {
        const list = url.split('/')
        return list[list.length - 1].split('.')[0]
      }
      
      export default {
        name: 'UpBase64',
        props: {
          defaultImageList: {
            type: Array,
            default: function () {
              return []
            },
            required: true,
          },
          // 组件展示样式
          uploadType: {
            type: Boolean,
            default: false,
            required: false,
          },
          // 文件类型列表
          fileTypeList: {
            type: Array,
            default: function () {
              return []
            },
            required: false,
          },
          // 容量大小
          limitSize: {
            type: Number,
            default: 2,
            required: false,
          },
          // 个数
          limitNum: {
            type: Number,
            default: 20,
            required: false,
          },
          // 是否支持多选
          multiple: {
            type: Boolean,
            default: false,
            required: false,
          },
          // 是否禁用
          disabled: {
            type: Boolean,
            default: false,
            required: false,
          },
          dwidth: {
            type: Number,
            default: 0,
            require: false,
          },
          dheight: {
            type: Number,
            default: 0,
            require: false,
          },
        },
      
        data() {
          return {
            previewVisible: false,
            progressVisible: false,
            progressValue: 10,
            previewImage: '',
            imageList: [],
          }
        },
      
        watch: {
          defaultImageList(newVal) {
            this.imageList = this.handleData(newVal)
          },
        },
      
        created() {
          this.imageList = this.handleData(this.defaultImageList)
        },
      
        methods: {
          // ---------------------------------------------img--start
          // 上传格式限制
          beforeImageUpload(file) {
            return new Promise((resolve, reject) => {
              if (this.fileTypeList.length != 0) {
                const index = this.fileTypeList.indexOf(file.type)
                if (index <= -1) {
                  this.$message.error(`您只能上传${this.fileTypeList}文件`)
                  return reject(new Error(`您只能上传${this.fileTypeList}文件,不能传${file.type}文件`))
                }
              }
              const limitSize = file.size / 1024 / 1024 < this.limitSize
              if (!limitSize) {
                this.$message.error(`文件大小不能大于${this.limitSize}MB`)
                return reject(new Error(`文件大小不能大于${this.limitSize}MB`))
              }
              const checkSize = this.checkImageWH(file, this.dwidth, this.dheight)
              return Promise.resolve(checkSize)
                .then(() => resolve())
                .catch((e) => {
                  reject(e)
                })
            })
          },
          checkImageWH(file, width, height) {
            // 参数分别是上传的file,想要限制的宽,想要限制的高
            const that = this
            return new Promise(function (resolve, reject) {
              let filereader = new FileReader()
              filereader.onload = (e) => {
                let src = e.target.result
                const image = new Image()
                image.onload = function () {
                  if ((width && this.width !== width) || (height && this.height !== height)) {
                    // 上传图片的宽高与传递过来的限制宽高作比较,超过限制则调用失败回调
                    const message = `图片宽高不满足,需要:宽 ${width || '不限制'},高 ${height || '不限制'}\n,当前图片宽:${
                      this.width
                    },高:${this.height}`
                    that.$message.error(message)
                    reject(new Error(message))
                  } else {
                    resolve({ width: this.width, height: this.height })
                  }
                }
                image.onerror = reject
                image.src = src
              }
              filereader.readAsDataURL(file)
            })
          },
      
          async handlePreview(file) {
            if (!file.url && !file.preview) {
              file.preview = await getBase64(file.originFileObj)
            }
            this.previewImage = file.url || file.preview
            this.previewVisible = true
          },
      
          handleCancel() {
            this.previewVisible = false
          },
          // 自定义上传逻辑
          customRequest({ action, file, onSuccess, onError, onProgress }) {
            this.progressVisible = true
            new Promise((resolve) => {
              const fileReader = new FileReader()
              // 转化为base64
              fileReader.readAsDataURL(file)
              fileReader.onload = async () => {
                let index = {
                  uid: this.genId(5),
                  name: file.name,
                  status: 'done',
                  url: fileReader.result,
                }
                let params = {
                  name: index.uid,
                  data: index.url,
                }
                try {
                  let res = await UploadImage(params)
                  index.url = res.result.url
                  if (res.status == 1) {
                    setTimeout(() => {
                      this.imageList = [...this.imageList.filter((item) => item.status === 'done'), index]
                      this.$message.success('文件上传成功!')
                      this.progressVisible = false
                      this.handleChange()
                      resolve(fileReader.result)
                    }, 2000)
                  } else {
                    this.imageList = [...this.imageList.filter((item) => item.status === 'done')]
                    this.$message.success(res.msg)
                    this.handleChange()
                    resolve(fileReader.result)
                  }
                } catch (error) {
                  console.log('upimg:', error)
                } finally {
                }
              }
            })
          },
          // 处理事件
          async handleImageChange(info) {
            try {
              // 删除图片
              let res = await DeleteImage(getName(info.file.url))
              console.log(res, 89)
              if (res.status == 1) {
                this.$message.success('删除成功!')
              } else {
                this.$message.error('删除失败!')
              }
            } catch (error) {
              // console.log('delimg:', error)
            } finally {
              let fileList = [...info.fileList]
              this.imageList = fileList
              this.handleChange()
            }
          },
      
          handleChange() {
            let index = this.imageList
              .filter((item) => item.url)
              .map((item) => {
                return item.url
              })
            // if (index?.length <= 0) return
            this.$emit('change', index ? index : [])
          },
      
          genId(length) {
            return Number(Math.random().toString().substr(3, length) + Date.now()).toString(36)
          },
      
          handleData(list) {
            return list.map((item) => {
              let index = this.genId(5)
              return {
                uid: index,
                name: index,
                status: 'done',
                url: item,
              }
            })
          },
      
          // ---------------------------------------------img--end
        },
      }
      </script>
      
      <style lang="less" scoped>
      .ant-upload-select-picture-card i {
        font-size: 32px;
        color: #999;
      }
      
      .ant-upload-select-picture-card .ant-upload-text {
        margin-top: 8px;
        color: #666;
      }
      </style>
      
      <style>
      .progress-container {
        width: 100px;
        height: 7px;
        background-color: #ffffff;
        border-radius: 5px;
      }
      
      .progress-bar {
        height: 100%;
        border-radius: 5px;
        animation-fill-mode: forwards;
        animation-name: progressBar;
        animation-iteration-count: infinite;
        background-color: #44cef6;
        animation-duration: 2s;
        animation-iteration-count: 1;
      }
      
      @keyframes progressBar {
        0% {
          width: 0%;
        }
      
        100% {
          width: 100%;
        }
      }
      </style>

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 11月25日
  • 已采纳回答 11月17日
  • 创建了问题 11月9日

悬赏问题

  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来