1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > vue-simple-uploader实现多文件/文件夹以及可拖拽上传

vue-simple-uploader实现多文件/文件夹以及可拖拽上传

时间:2021-11-27 17:36:30

相关推荐

vue-simple-uploader实现多文件/文件夹以及可拖拽上传

vue-simple-uploader的简单使用

1.效果图展示2.安装3.vue2使用(vue3使用会报错)4.代码

vue-simple-uploader是基于simple-uploader.js的vue上传组件支持多文件/文件夹上传,拖拽上传可暂停、继续上传上传错误处理支持“秒传”,通过文件判断服务端是否已存在从而实现“秒传”支持进度、预估剩余时间、出错自动重试、重传等操作

这里有参考文档和事例

1.效果图展示

后面有使用拖拽上传文件/文件夹

上传遇到同名的文件会有一个弹框提示,并有相关的操作

2.安装

npm install vue-simple-uploader --save

3.vue2使用(vue3使用会报错)

import uploader from 'vue-simple-uploader'//已经创建Vue实例了Vue.use(uploader)

4.代码

这里我只贴主要的内容,代码也都给有注释哦

<uploaderref="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-btnid="uploader_btn"ref="uploadBtn">选择文件</uploader-btn><uploader-btnid="uploader_btn"ref="uploadFolderBtn":directory="true">选择文件夹</uploader-btn>//可拖拽的区域<uploader-drop class="drop">//我把这个table区域变成可拖拽的了 具体看自己写的内容吧<el-table></el-table></uploader-drop>//这是上传文件显示的上传弹框,在右下角 有文件上传时显示 默认是隐藏<divv-show="isShowDropUploadFileLists"class="drog_list"><uploader-list><divslot-scope="props"class="file-panel":class="{ collapse: collapse }"><div class="file-title"><div class="title">文件列表</div><div class="operate"><el-buttontype="text":title="collapse ? '展开' : '折叠'"@click="collapse = !collapse"><i :class="collapse ? 'el-icon-full-screen' : 'el-icon-minus'" /></el-button><el-buttontype="text"title="关闭"@click="CloseFilesUploadList"><i class="el-icon-close" /></el-button></div></div><ul class="file-list"><liv-for="file in props.fileList":key="file.id"class="file-item":class="`file-${file.id}`"><uploader-fileref="files":class="'file_' + file.id":file="file":list="true"/></li><divv-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: "/api/Files",//上传地址,如果有文件上传地址不同时 可以是个函数来改变testChunks: false,//测试每个块是否在服务端已经上传了allowDuplicateUploads: true, // 一个文件以及上传过了是否还允许再次上传query: (file, chunk) => {//上传时所带的参数 可以是个函数在选择文件时 自定义(拿到的两个参数分别是Uploader.File 实例、当前块 Uploader.Chunk 以及是否是测试模式)return {...file.params,isUseLastVersionFieldValueWhenUpdate: false, // 請帶falsepath: 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] // 同名文件列表// 保存批量文件IDthis.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 = trueconsole.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;},}}

遇到同名文件弹框的操作

<SameFileInforef="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>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。