大文件切片上传,支持断点上传

最近项目中遇到了大文件上传在IE下经常崩溃,这里我找到一个非常好用的插件分享给大家vue-simple-uploader
读这篇文章之前,建议先读一遍simple-uploader.js的文档
请添加图片描述

直接上代码
安装 npm install vue-simple-uploader --save

使用:在main.js中:

import uploader from 'vue-simple-uploader'
Vue.use(uploader)

注册全局组件
html

<template>
    <el-dialog 
        title="上传大资源" 
        :visible="isShowUP"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        center
        width="50%"
        append-to-body
        @close="handelClose"
    >
        <uploader
            ref="uploader"
            :options="options"
            :file-status-text="statusText"
            :auto-start="false"
            class="uploader-example"
            @file-added="onFileAdded"
            @file-success="onFileSuccess"
            @file-error="onFileError"
            @file-removed="fileRemoved"
        >
            <uploader-btn v-show="show_up" single style="background-color: #67C13B">
                <i class="el-icon-upload" style="margin-right: 5px"></i>上传文件</uploader-btn>
            <uploader-list></uploader-list>
        </uploader>
        <div slot="footer" class="dialog-footer">
            <el-button v-show="!done" @click="cancelUpload">取消上传</el-button>
            <el-button v-show="done" type="success" @click="handelClose(true)">完成上传</el-button>
            <el-button type="primary" @click="submitUpload">开始上传</el-button>
        </div>
    </el-dialog>
</template>

script

import { mapActions } from "vuex";
import { showError,showLoading,showMessage } from '../../utils';

export default {
    name: "UPLoder",
    props:{
        visible: {
            type: Boolean,
            default: false
        },
    },
    data() {
        return {
            isShowUP:false,  // 弹窗开关
            show_up: true,   // 选择文件按钮
            done: false,     // 完成,取消
            options: {
                target: "/api/uploader/save", // 上传地址
                maxChunkRetries: 2, // 失败重试
                chunkSize: 10 * 1024 * 1024, // 分片大小
                simultaneousUploads: 3, //并发上传数
                query: {   // 携带参数
                    type: "attach",
                    id: "",
                    appId:this.$store.state['cms/site'].site.id
                },
                headers: { // 头信息
                    token: this.$store.state.authen.token
                }
            },
            uploaderData:null,  // 成功后返回路径
            statusText: {       // 提示语
                success: "上传成功",
                error: "上传失败",
                uploading: "上传中",
                paused: "暂停中",
                waiting: "等待中"
            },
            uploadType:{    // 类型
                image:['jpg','jpeg','png','svg','gif'],
                video:['mp4','avi','mpeg','webm','ogg'],
                audio:['wav','mp3','wma']
            },
        };
    },
    watch: {
        visible(v) {
            this.isShowUP = v
        },
    },
    methods: {
        ...mapActions("authen", ["combine"]),  // 合并接口
        //添加文件到列表还未上传,每添加一个文件,就会调用一次,在这里过滤并收集文件夹中文件格式不正确信息,同时把所有文件的状态设为暂停中
        onFileAdded(file) {
            // 这里只做单文件上传 所以选择文件按钮隐藏
            this.show_up = false  
            // 携带唯一id
            this.options.query.id = file.uniqueIdentifier + "-" + new Date().getTime();
            // 获取选择文件的后缀
            let file_type = file.name.substring(file.name.lastIndexOf(".") + 1);
            // 进行判定类型   默认为附件(attach)
            this.uploadType.image.forEach(tp=>{
                file_type==tp && (this.options.query.type = 'image')
            })
            this.uploadType.video.forEach(tp=>{
                file_type==tp && (this.options.query.type = 'video')
            })
            this.uploadType.audio.forEach(tp=>{
                file_type==tp && (this.options.query.type = 'audio')
            })
        },
        //每个文件传输给后端之后,返回的信息
        onFileSuccess(rootFile, file, response, chunk) {
            // 返回的信息是字符串形式,对其进行转换
            let res = JSON.parse(response);
            // 如果成功
            if (res.success) {
                showLoading(true,'正在合并...')
                // 发送合并请求
                this.combine({
                    id: this.options.query.id,
                    type: this.options.query.type,
                    filename: file.name
                }).then(res => {
                    // 接收相应
                    this.uploaderData = {type:this.options.query.type,data:res.data}
                    // 切换完成按钮
                    this.done = true;
                    showMessage('上传成功!')
                    showLoading()
                });
            } else {
                showError(res.errMsg)
                showLoading()
            }
        },
        // 上传错误触发,文件还未传输到后端
        onFileError(rootFile, file, response, chunk) {
            showError('文件上传失败')
        },
        // 移除文件
        fileRemoved(file) {
            this.$nextTick(() => {
                this.show_up = true;
                this.done = false;
            });
        },
        //点击开始上传按钮
        submitUpload() {
            this.$nextTick(() => {
                for (var i = 0; i < this.$refs["uploader"].files.length; i++) {
                    this.$refs["uploader"].files[i].resume();
                }
            });
        },
       
        // 上传弹框关闭
        handelClose(v=false) {
            this.clearcache()
            this.$emit('closePublishModal', false)
            // 判断是完成还是关闭
            v && this.$emit('uploaderData',this.uploaderData)
        },
        // 清除缓存
        clearcache() {
            this.show_up = true;
            this.done = false;
            this.options.query.id = ''
            this.options.query.type = 'attach'
            this.$refs.uploader.uploader.cancel();
        },
        //取消上传
        cancelUpload() {
            this.thirdDialog = false;
            this.clearcache();
        }
    }
};

style

<style lang="scss">
.dialog-footer {
    text-align: center;
}
.uploader-example .uploader-btn {
    margin-right: 8px;
    color: #ffffff;
    border: #ffffff;
}
.uploader-file{
    margin-top: 10px;
    border: 1px solid #ccc;
    .uploader-file-icon {
        &:before {
            content: '' !important;
        }
        &[icon=image] {
            background: url(./image/image-icon.png);
        }
        &[icon=video] {
            background: url(./image/video-icon.png);
        }
        &[icon=document] {
            background: url(./image/text-icon.png);
        }
        &[icon=audio]:before {
            content: "\1F3B5" !important;
        }
        &[icon=unknown]:before {
            content: "\1F4C3" !important;
        }
    }
}

有疑问,有问题,有好点子欢迎指教^v^ ^v^ ^v^ ^v^ ^v^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值