乐趣区

关于vue.js:阿里云OSS文件上传及vue-axios终止当前请求

一、前言

在我的项目中,很多状况下咱们都会用到文件上传,然而当某个文件太大,或者不小心选错了文件时,咱们就须要终止以后的申请,从新上传文件。同时也能进步网站性能,去除多余申请。

二、代码

当初咱们上传文件,很多都会上传到 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>

三、结语

应用场景:
  • 页面中新增弹层中有须要上传文件,点敞开弹层按钮时须要终止以后申请。
  • 文件上传谬误,须要点击勾销,从新抉择。
  • 屡次申请时,终止上一次申请,例如搜寻框,每输出一个字符都要发送一次申请,但输出过快的时候其实后面的申请并没有必要真的发送进来。
退出移动版