上传图片过程中,关闭了弹框 如何取消上传

浪尽此生 提交于 2019-12-03 11:02:34

在开发过程中遇到了这种情况, 当在新建某个内容时 (弹框展示 ),图片上传过程中 若是关闭的弹框 图片仍然在上传 可能导致一些错误的发生

两种解决方案:

1 图片上传完成之前讲关闭或提交或取消的按钮都置为不可用的状态 ,这样就避免了上面情况的发生;

2 关闭弹框时取消图片的上传 

  这里需要引入axios 的 source 的token

<template>
  <div class="app-container">
    <div class="search-container">
      <el-button type="primary" plain @click="handleNew()">新建</el-button>
    </div>
    <el-dialog
      title="新建"
      :close-on-click-modal="!dialogVisible"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose"
    >
      <el-form ref="newFormModel" :model="newObj" :rules="rules">
        <el-form-item class="my-el-form-item" prop="img" label="logo">
          <el-upload
            ref="fileupload"
            class="avatar-uploader"
            action
            :limit="1"
            :disabled="uploadLoading"
            :show-file-list="false"
            :http-request="getFile"
            :on-success="handleAvatarSuccess"
            accept=".png, .jpg"
          >
            <img v-if="newObj.img&&newObj.img.length>0" :src="newObj.img" class="avatar" />
            <el-button
              :class="newObj.img?'buttonIconC':''"
              :disabled="uploadLoading"
              size="small"
              type="primary"
            >点击上传</el-button>
          </el-upload>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <!-- 方案一的解决方案 下面相关source 的内容删掉既可-->
        <!-- <el-button :disabled="uploadLoading" @click="handleClose()">取 消</el-button>
        <el-button type="primary" :disabled="uploadLoading" @click="newSubmit()">确 定</el-button>-->
        <!-- 方案二 -->
        <el-button @click="handleClose()">取 消</el-button>
        <el-button type="primary" @click="newSubmit()">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { uplaodImageApi } from '@/api/apiFile'
export default {
  data() {
    return {
      CancelToken: null,
      source: null,
      dialogVisible: false,
      uploadLoading: false,
      rules: {
        img: [
          { required: true, message: '请选择需要上传的ogo', trigger: 'change' }
        ]
      },
      newObj: {
        img: ''
      }
    }
  },
  watch: {
    // 监控当 上传文件过程中突然关闭弹框 取消文件的上传 uploadLoading表示是否在上传中
    dialogVisible: function(newVal, oldVal) {
      if (newVal === false && oldVal === true && this.uploadLoading) {
        // 取消请求(message 参数是可选的)
        this.source.cancel('Image upload cancelled.')
        // 取消上传之后做一些初始化工作
        this.resetForm()
      }
    }
  },
  beforeMount() {
    this.CancelToken = this.axios.CancelToken
    this.source = this.CancelToken.source()
  },
  methods: {
    handleNew() {
      this.dialogVisible = true
    },
    resetForm() {},
    handleClose() {
      this.dialogVisible = false
    },
    newSubmit() {},
    uplaodImageFile(img) {
      const _self = this
      const formData = new FormData()
      formData.append('file', img)
      this.source = this.CancelToken.source()
      uplaodImageApi(formData, this.source.token)
        .then(response => {
          this.$message({
            message: 'Upload success',
            type: 'success'
          })
          this.newObj.img = response.data.url          //上传成功之后 清空表单验证中的部分img内容
          this.$refs['newFormModel'].clearValidate('img')
          setTimeout(function() {
            _self.handleAvatarSuccess()
          }, 2000)
        })
        .catch(msg => {
          if (this.axios.isCancel(msg)) {
            // 注意:在此处清空source 因为 不清空会使下次的请求 会被默认取消
            this.source = {}
            console.log('Request canceled', msg)
          } else {
            this.$message({
              message: msg || 'Upload Error',
              type: 'error'
            })
            this.handleAvatarSuccess()
          }
        })
    },
    getFile(value) {
      this.uploadLoading = true
      const img = value.file
      if (this.beforeAvatarUpload(img)) {
        this.uplaodImageFile(img)
      } else {
        this.handleAvatarSuccess()
      }
    },
    handleAvatarSuccess(res, file) {
      this.uploadLoading = false
      this.$refs['newFormModel'].validateField('img')
      this.$refs.fileupload.clearFiles()
    },
    beforeAvatarUpload(file) {
      const isJPG = file.type === 'image/jpeg'
      const isPNG = file.type === 'image/png'
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isJPG && !isPNG) {
        this.$message.error('上传头像图片只能是 JPG或PNG 格式!')
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 2MB!')
      }
      return isLt2M && (isJPG || isPNG)
    }
  }
}
</script>

注意: 在过程中可以会报错    Cannot read property 'source' of undefined  

上面错误原因在于 引入axios方式不对 ,上面的source 也可能是protool 或者 CancelToken都是因为 在注入axios时方式不对

axios 并不是 vue的插件 而是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中;所以使用时不能使用 Vue.use(axios),如此使用会报上面的错误;

需要将axios 绑定到 vue实例的原型上面

import axios from 'axios'
Vue.prototype.axios = axios

参考文档:

   http://www.axios-js.com/zh-cn/docs/  

   https://github.com/axios/axios

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!