赞
踩
后面有使用拖拽上传文件/文件夹
上传遇到同名的文件会有一个弹框提示,并有相关的操作
npm install vue-simple-uploader --save
import uploader from 'vue-simple-uploader'
//已经创建Vue实例了
Vue.use(uploader)
这里我只贴主要的内容,代码也都给有注释哦
<uploader ref="uploader" :options="options" :auto-start="false" :file-status-text="fileStatusText" class="uploader-example" @file-added="onFileAdded" @files-added="onFilesAdded" @file-error="onFileError" @file-complete="onFileComplete" > <uploader-unsupport /> //不支持上传时显示内容 //这个组件也有两个上传的按钮 但是我这边给隐藏了 自定义了下拉框 点击的时候 获取对应的实例 然后触发点击事件 <uploader-btn id="uploader_btn" ref="uploadBtn" >选择文件</uploader-btn> <uploader-btn id="uploader_btn" ref="uploadFolderBtn" :directory="true" >选择文件夹</uploader-btn> //可拖拽的区域 <uploader-drop class="drop"> //我把这个table区域变成可拖拽的了 具体看自己写的内容吧 <el-table></el-table> </uploader-drop> //这是上传文件显示的上传弹框,在右下角 有文件上传时显示 默认是隐藏 <div v-show="isShowDropUploadFileLists" class="drog_list" > <uploader-list> <div slot-scope="props" class="file-panel" :class="{ collapse: collapse }" > <div class="file-title"> <div class="title">文件列表</div> <div class="operate"> <el-button type="text" :title="collapse ? '展开' : '折叠'" @click="collapse = !collapse" > <i :class="collapse ? 'el-icon-full-screen' : 'el-icon-minus'" /> </el-button> <el-button type="text" title="关闭" @click="CloseFilesUploadList" > <i class="el-icon-close" /> </el-button> </div> </div> <ul class="file-list"> <li v-for="file in props.fileList" :key="file.id" class="file-item" :class="`file-${file.id}`" > <uploader-file ref="files" :class="'file_' + file.id" :file="file" :list="true" /> </li> <div v-if="!props.fileList.length" class="no-file" > <i class="iconfont icon-empty-file" /> 暂无待上传文件 </div> </ul> </div> </uploader-list> </div> </uploader>
相关js我是单独拎出来了然后通过mixins混入到当前vue文件了
import { GetBatchFilesId, GetDocumentSameNameInfo } from "@/api/file"; //批量上传获取ID,对比上传文件是否跟已存在的同名的两个接口 import { CreateFilePath, CreateFileName } from "@/utils/handleFile";//这个是入参对文件/文件夹路径和名字的处理 export default { data () { return { options: { target: "http://test.hhh.com.cn/api/Files",//上传地址,如果有文件上传地址不同时 可以是个函数来改变 testChunks: false,//测试每个块是否在服务端已经上传了 allowDuplicateUploads: true, // 一个文件以及上传过了是否还允许再次上传 query: (file, chunk) => { //上传时所带的参数 可以是个函数在选择文件时 自定义(拿到的两个参数分别是Uploader.File 实例、当前块 Uploader.Chunk 以及是否是测试模式) return { ...file.params, isUseLastVersionFieldValueWhenUpdate: false, // 請帶false path: CreateFilePath(file.relativePath, true), autoIdNamingType: "Auto", // 自动编码 directoryId: 14, // 项目ID }; }, }, fileStatusText: {//显示的状态 success: "上传成功", error: "上传失败", uploading: "上传中", paused: "已暂停", waiting: "等待上传", }, } }, computed: { // 获取上传文件实例 uploaderRef() { return this.$refs.uploader.uploader; }, }, methods: { //值得注意的是我这个方法是@files-added="onFilesAdded",是对当前一次性上传的所有文件做的处理,比如说上传5个文件 那就是会获得一个数组里面包括5个文件,这个函数是在file-added全部执行完后走一次 // @file-added="onFileAdded"获取到的单个当前上传文件,按照上传顺序来的,比如说上传5个文件,那这个函数会执行5次 // 全部文件处理 onFilesAdded (files, filelist) { this.nowUploadFiles = [...files]//当前上传的文件列表保存了一下 后面有同名弹框操作后 方便继续上传文件 不然触发到同名文件弹框了 后续的操作获取不到已经上传到一半的文件了 let getBatchIds = '' const filesLength = files.length // 调用文件同名验证接口,这边入参用的都formData格式 var formdata = new FormData(); formdata.append("id", 3); formdata.append("directoryId", 6); formdata.append("isReserveDirStructure", true); this.fileList.forEach((v) => { formdata.append("paths[]", v); }); this.fileNameList.forEach((v) => { formdata.append("filenames[]", v); }); this.fileList = [] this.fileNameList = [] const getSameFileInfo = new Promise((resolve, reject) => { formdata.append("autoIdNamingType", "Auto"); GetDocumentSameNameInfo(formdata).then(_res => { resolve(_res) }).catch(err => reject(err)) }) if (filesLength > 1) { //多文件或者文件夹上传的时候 入参需要带个批量ID 看自己需求哈 // 批量上传文件 getBatchIds = new Promise((resolve, reject) => { formdata.append("isTemp", false); GetBatchFilesId(formdata).then(_res => { resolve(_res) }).catch(err => reject(err)) }) } Promise.all([getSameFileInfo, getBatchIds]).then(res => { if (res && res.length) { // 同名文件对比弹框弹出 this.isShowSameFiledialog = !!(res[0] && res[0].length) this.isShowSameFileInfo = res[0] // 同名文件列表 // 保存批量文件ID this.BatchUploadId = res[1].BatchUploadId || '' if (!this.isShowSameFiledialog) { // 单个文件无同名时直接上传,不显示弹框 console.log(files[0].name) files.forEach(item => { item.params = { sameNameUpdateisTrue: this.sameNameUpdateisTrue, // 遇到同名檔案是否更版 isReserveDirStructure: false, } item.resume(); }) // 显示上传文件弹框 this.isShowDropUploadFileLists = true console.log('单个文件无同名时直接上传,不显示弹框') } } }).catch(err => console.log(err, '哈哈哈')) }, // 文件上传获取单个文件 onFileAdded (file, fileList) { const _dataPath = file.relativePath; // 获取到文件的路径数组和对应的文件名数组 this.fileList.push(CreateFilePath(_dataPath, this.isFromDragDrop)); this.fileNameList.push(CreateFileName(_dataPath)); }, // 根文件上传成功 onFileComplete (rootFile) { this.$message({ message: "上传成功!", type: "success", }); }, // 文件上传失败 onFileError (file) { this.$message({ message: "上传失败,请重试!", type: "error", }); }, // 点击关闭按钮 CloseFilesUploadList () { this.uploaderRef.cancel(); this.isShowDropUploadFileLists = false; }, } }
遇到同名文件弹框的操作
<SameFileInfo ref="sameFileDailog" :isshow="isShowSameFiledialog" //显示弹框 :same-file-info="isShowSameFileInfo"//同名文件数据列表 @handelUpdateFile="handelUpdateSameNameFile" /> // 同名文件弹框操作 handelUpdateSameNameFile(type) { if (type === "cancel") { //取消操作 this.nowUploadFiles && this.nowUploadFiles.forEach((item) => { item.ignored = true; }); this.uploaderRef.cancel(); //关闭上传 uploaderRef是组件uploader的实例 this.isShowDropUploadFileLists = false; //关闭上传文件列表 // 关闭弹框 this.isShowSameFiledialog = false; return false; } if (type === "skip") {//跳过 // 点击跳过 this.sameNameUpdateisTrue = false; // 过滤掉重名的文件 const _this = this; _this.nowUploadFiles && _this.nowUploadFiles.forEach((v) => { _this.isShowSameFileInfo.forEach((val) => { if (val.DocumentName.split(".")[0] === v.name.split(".")[0]) { v.ignored = true; //给当前上传的文件列表中同名文件都加一个属性,后续过滤掉同名文件不上传 } }); }); } else if (type === "replace") { this.sameNameUpdateisTrue = true; } else if (type === "add") { this.sameNameUpdateisTrue = false; } // 给上传插件赋值(传参) this.nowUploadFiles && this.nowUploadFiles.forEach((item) => { item.params = { sameNameUpdateisTrue: this.sameNameUpdateisTrue, // 遇到同名檔案是否更版 isReserveDirStructure: true, // 是否保留本地文件夾結構 (單檔可帶false) batchUploadId: this.BatchUploadId, }; if (item.ignored) { this.uploaderRef.removeFile(item); //如果有同名过滤属性的则选择不上传 } item.resume(); }); // 关闭弹框 this.isShowSameFiledialog = false; // 显示上传文件弹框 this.isShowDropUploadFileLists = true; },
大致逻辑都在这里了
最后贴一下样式代码吧
<style lang="scss"> #uploader_btn { position: absolute; clip: rect(0, 0, 0, 0); } .drog_list { position: fixed; z-index: 20; right: 15px; bottom: 15px; width: 520px; box-sizing: border-box; .file-panel { background-color: #fff; border: 1px solid #e2e2e2; border-radius: 7px 7px 0 0; box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); .file-title { display: flex; height: 40px; line-height: 40px; padding: 0 15px; border-bottom: 1px solid #ddd; .operate { flex: 1; text-align: right; i { font-size: 18px; } } } .file-list { position: relative; height: 240px; overflow-x: hidden; overflow-y: auto; background-color: #fff; transition: all 0.3s; list-style: none; padding: 0 2%; font-size: 12px; .file-item { background-color: #fff; } ::v-deep .uploader-file-size { text-indent: 0 !important; } ::v-deep .uploader-file-status { width: 22%; } ::v-deep .uploader-file-name { display: flex; align-items: center; .uploader-file-icon { margin-top: 0; margin-right: 0; } } ::v-deep .uploader-file-meta { display: none; } ::v-deep .uploader-file-actions { width: 12%; float: right; } } &.collapse { .file-title { background-color: #e7ecf2; } .file-list { height: 0; } } } } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。