首页 / JavaScript   vue  

vue中vue2-dropzone 多文件上传插件的使用

下载依赖包 推荐使用cnpm 
cnpm install vue2-dropzone --save


vue-dropzone的github地址 :https://github.com/rowanwins/vue-dropzone
dropzone.js官网 :https://www.dropzonejs.com

vue2-dropzone有提供许多的events事件,但是在使用的时候我们一般只需要一个添加成功后的回调事件(vdropzone-success)和删除文件的回调事件(vdropzone-removed-file)基本上可以满足我们的一个业务需求


使用方式

在一个.vue文件中直接引入vue2-dropzone组件

<vue-dropzone ref="myVueDropzone" id="dropzonearea" 
            :options="dropzoneOptions" 
            :useCustomSlot=true 
            :include-styling="false" 
            v-on:vdropzone-success="uploadSuccess"
            v-on:vdropzone-removed-file="removedFile"
        >
    <!--自定义拖拽区域中的提示信息-->
    <div class="resumeDragWrap defaultMessageWrap">
        <div class="resumeTipsBg">
            <div class="resumeTipsTitle">上传或拖拽上传</div>
            <div class="resumeTipsCon">仅支持:.rar .zip .doc .docx .html .pdf .jpg .png格式的文件</div>
        </div>
    </div>
</vue-dropzone>

import vue2Dropzone from 'vue2-dropzone'  // 导入组件
export default {
name: 'selfAddWrap',
    components: {
        vueDropzone: vue2Dropzone
    },
data(){
    return{
       dropzoneOptions: {
                url: '/admin/add_resume/resumeEnclosureUpload', // 文件上传接口
                previewTemplate: this.template(),  // 自定义文件上传后显示的样式
            }
    }
},
methods:{
    // 自定义文件上传后显示的样式
template(){
        return `<div class="dz-preview dz-file-preview">           
                    // 必须在在这个容器中自定义布局样式
                </div>`;
    },
    // 文件上传成功回调该方法,获取服务器响应信息
    uploadSuccess(file, response){
        if(response.code == 200) {
            file.upload.file_url = response.data  // 记录文件上传后保存在服务端的路径,用于后续提交存入数据库
        }else{
            let errorEle,preview
            errorEle = file.previewElement.querySelector(".error-message");
            errorEle.innerHTML= `<i class="el-icon-warning-outline"></i>&nbsp;`+response.msg   // 自定义显示异常提示
            preview = file.previewElement
            preview.style.background  = "rgba(235,103,81,0.1)"
            preview.style.borderColor = "#fdefed"
        }
    },
    // 移除文件并在服务端删除该文件
    removedFile(file, error, xhr){
        if(file.upload.file_url){
            let formData = new FormData(); // 通过FormData 传输file二进制文件数据
            formData.append('filePath', file.upload.file_url);
            let xhr = new XMLHttpRequest();
            // 接收response信息
            xhr.onload = function () {
                // var json = JSON.parse(xhr.responseText);
                // console.log(json)
                // ... 这里处理返回的json数据
            };
            xhr.open('POST', '/admin/add_resume/remFileByPath', true);
            xhr.send(formData)
        }
    },
}
}

vue-dropzone 的几个属性解释

:useCustomSlot=true   // 自定义拖拽区域的提示信息
:include-styling="false"   // 屏蔽插件自定的样式

v-on:vdropzone-success="uploadSuccess"     // 自定义事件 上传成功后调用 
v-on:vdropzone-removed-file="removedFile"  // 自定义事件 把文件从拖拽区域移除后调用

ref="myVueDropzone"   // 用于获取插件的dom节点,调用提供的方法;如提交表单时我们可以使用 :let files = this.$refs.myVueDropzone.getAcceptedFiles()  // 获取全部的附件信息,根据需要获取有用的信息提交入库  


自定义显示模版需要注意几个点 previewTemplate: this.template()

如果我们希望自定义的模版可以显示:异常提示、进度条、文件大小、自定义文件名等等需要在显示的标签上加对应的属性

template: function () {
        return `<div class="dz-preview dz-file-preview">
                <div class="dz-image">
                    // data-dz-thumbnail-bg 显示base64格式的图
                    <div data-dz-thumbnail-bg></div> 
                </div>
                <div class="dz-details">
                    // data-dz-size 显示文件大小
                    <div class="dz-size"><span data-dz-size></span></div>
                    // data-dz-name 显示文件名
                    <div class="dz-filename"><span data-dz-name></span></div>
                </div>
                // data-dz-uploadprogress 显示上传进度条  (注意 span 标签必须设置为inline-block)
                <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
                // data-dz-errormessage 显示上传异常信息
                <div class="dz-error-message"><span data-dz-errormessage></span></div>
                // data-dz-remove 移除文件的,这个会触发 vdropzone-removed-file 事件调用 removedFile方法
                <div class="dz-error-mark"><i class="fa fa-close"  data-dz-remove></i></div>
            </div>
        `;
      },

注:如果自定义模板样式不起作用,可以把样式全部写成行内样式

自己定义的模板

template(){
        return `<div class="dz-preview dz-file-preview" style="background:#F9FAFC;">           
                    <div class="enclosureUploadWrap" style="position: relative;border:1px solid #EBEBEB;margin-bottom:7px;border-radius:4px;">
                        <i class="el-icon-picture-outline fileIconWrap" style="margin-left: 10px; margin-right: 8px; font-size: 16px;vertical-align: sub;"></i>
                        <div class="resumeUploading" style="display:inline-block;">
                            <span class="dz-filename" data-dz-name></span>
                            <span style="color:#E66751;margin-left:20px;display:inline-block;" class="dz-error-message"><span data-dz-errormessage class="error-message"></span></span>
                            <div class="dz-progress" style="display:inline-block;width:100px;height:8px;border-radius:4px;position:absolute;top:11px;right:20%;background:#ebeef5;">
                                <span  class="dz-upload " style="display:inline-block;background: rgb(176, 189, 201);width:0%;height:100%;position:absolute;top:0px;left:0px;border-radius:4px;" data-dz-uploadprogress></span>
                            </div>
                            <div class="dz-size"  style="position:absolute;top:0px;right:15%;display:inline-block;height:30px;line-height:30px;"><span data-dz-size></span></div>
                        </div>
                        <div class="resumeDealIcon " style="position:absolute;top:0px;right:20px;color:red;inline-block;font-size:14px;padding-left:20px;">
                                <span><i class="el-icon-delete" data-dz-remove></i></span>
                        </div>
                    </div>
                </div>`;
    },


后端服务器接收上传的二进制文件(TP5为例)

虽然说是多文件上传,但是调用上传接口时,并不是一次性把所有文件的二进制数据都传到服务端,而是分块上传,即上传多少个文件就会调用多少次接口,单独上传二进制文件数据到后端

/**
     * des:简历附件上传
     */
    public function resumeEnclosureUpload() {

        $file = request()->file('file'); // 获取上传的二进制文件数据

        $uploadObjec = new UploadFileController();

        $info = $uploadObjec->fileUpload($file);

        return json($info);
    }




2019-11-01