在開發過程中遇到了這種情況, 當在新建某個內容時 (彈框展示 ),圖片上傳過程中 若是關閉的彈框 圖片仍然在上傳 可能導致一些錯誤的發生
兩種解決方案:
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