一、前言
在我的项目中,很多状况下咱们都会用到文件上传,然而当某个文件太大,或者不小心选错了文件时,咱们就须要终止以后的申请,从新上传文件。同时也能进步网站性能,去除多余申请。
二、代码
当初咱们上传文件,很多都会上传到 OSS,当初以阿里云的 OSS 上传为例 ( 仅为前端代码,Vue 实例):
uplodaFile 组件封装
<template>
<div :class="$style.uploadPack">
<input type="file" @change="$_onUpload" />
<slot />
</div>
</template>
<script>
import {commonService} from '@/common/service' // 封装的接口申请,依据我的项目状况而定
import axios from 'axios'
export default {
methods: {async $_onUpload(e) {this.$emit('input', { status: 'begin', data: null})
const files = e.target.files
let formData = new FormData()
const fileName = files[0].name
/**
getOssToken 返回的数据格式
{
expire: 1607499265904
params: {
signature: "1",
OSSAccessKeyId: "1",
key: "1",
policy: "1",
success_action_status: "200",
x-oss-security-token: "1"
},
url: "http://xxx.aliyuncs.com"
}
*/
const {data} = await commonService.getOssToken({filename: fileName}) // 获取阿里云 oss 返回的数据
Object.keys(data.result.params).forEach(key => {formData.append(key, data.result.params[key])
})
formData.append('file', files[0])
const self = this
try {
/**
* 留神此处接口没有数据返回 只有状态
* 胜利后须要本人依据 getOssToken 接口返回的数据组装返回
*/
await axios.post(data.result.url, formData, {cancelToken: new axios.CancelToken(function executor(c) {self.source = c}),
})
/**
* 通过同步数据给父组件
*/
this.$emit('input', { status: 'end', data: { file_name: fileName, url: data.result.url + '/' + data.result.params['key'] } })
/**
* 上传胜利后清空表单,防止重名文件不再次执行 change 事件
*/
e.target.value = ''
} catch (err) {
/**
* 是否是手动终止勾销 导致的失败
*/
if (axios.isCancel(err)) {this.$message.error(err.message)
} else {this.$message.error('上传失败')
}
this.$emit('input', { status: 'end', data: {} })
e.target.value = ''
}
},
/**
* 终止上传接口申请
*/
cancelRequest() {if (typeof this.source === 'function') {this.source('勾销文件上传')
}
},
},
}
</script>
<style lang="scss" module>
.uploadPack {
position: relative;
overflow: hidden;
input {
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
opacity: 0;
}
}
</style>
组件应用
<template>
<div>
<uploadPack v-model="packInfo" ref="uploadPack">
<a-button :loading="loading" type="primary"> 上传 </a-button>
</uploadPack>
<a-button @click="cancelRequest"></a-button>
</div>
<template>
<script>
export default {data() {
return {
loading: false,
fileData: {},}
},
watch: {
/**
* 监听文件上传的数据变动
*/
packInfo(newValue) {if (newValue.status === 'begin') {this.loading = true} else if (newValue.status === 'end') {
this.loading = false
this.fileData = newValue.data
}
}
},
methods: {
/**
* 终止上传
*/
cancelRequest() {this.$refs['uploadPack'] && this.$refs['uploadPack'].cancelRequest()}
}
}
<script>
三、结语
应用场景:
- 页面中新增弹层中有须要上传文件,点敞开弹层按钮时须要终止以后申请。
- 文件上传谬误,须要点击勾销,从新抉择。
- 屡次申请时,终止上一次申请,例如搜寻框,每输出一个字符都要发送一次申请,但输出过快的时候其实后面的申请并没有必要真的发送进来。