介绍:由于element的el-upload不支持文件夹上传,所以用了vue-simple-uploader,实现了文件夹/文件的携带form data 和 headers参数上传。vue-simple-uploader还能用于切分上传、断续上传,此处项目没有用到。
想对上传做更多的处理的小伙伴,推荐去看源码。
另:以下代码加了文件列表的拖拽。
1、安装:
npm
install vue-
simple-uploader
—
save
在main.js里 加上:
import uploader from 'vue-simple-uploader'
Vue.use(uploader)
2、
<uploader
ref="uploader"
:options="options"
:autoStart="false"
@file-added="onFileAdded"
@file-success="onFileSuccess"
@file-progress="onFileProgress"
@file-error="onFileError"
@class="uploader-app"
>
<uploader-unsupport></uploader-unsupport>
<uploader-btn id="global-uploader-btn" :attrs="attrs" ref="uploadBtn">{{$t('imgUpload.file')}}</uploader-btn>
<uploader-btn :directory="true">{{$t('imgUpload.folder')}}</uploader-btn>
<uploader-list v-show="panelShow">
<div id="filePanel"
v-drag
draggable="false"
class="file-panel"
:class="{'mini': collapse}"
slot-scope="props"
>
<div class="file-title">
<h2>文件列表</h2>
<div class="operate">
<el-button @click="fileListShow" type="text">
<i :class="collapse ? 'el-icon-plus': 'el-icon-minus'"></i>
</el-button>
<el-button @click="close" type="text" title="关闭">
<i class="el-icon-close"></i>
</el-button>
</div>
</div>
<ul class="file-list">
<li v-for="file in props.fileList" :key="file.id">
<uploader-file :class="'file_' + file.id" ref="files" :file="file" :list="true"></uploader-file>
</li>
<div class="no-file" v-if="!props.fileList.length">
<i class="nucfont inuc-empty-file"></i> 暂无待上传文件
</div>
</ul>
</div>
</uploader-list>
</uploader>
3、
options: {
target: process.env.API_ROOT + "/api/File/UploadByBuffer",//地址
testChunks: false, //不校验
chunkSize: "10240000",
fileParameterName: "file", //上传文件时文件的参数名,默认file
maxChunkRetries: 3, //最大自动失败重试上传次数
query:{
//form data里的参数 根据实际需要
},
headers: {
// 在header中添加的验证 根据实际需要
}
},
panelShow: false, //上传列表的显示
attrs: {
// 接受的文件类型 根据实际需要
accept: [".zip", ".rar"]
},
collapse: false ,//列表的缩放
curTop:undefined,//标记当前列表的位置
curLeft:undefined,//标记当前列表的位置
4、
//添加文件到列表 还未上传
onFileAdded(file) {
this.panelShow = true;
//设置headers等参数的值
},
//上传成功
onFileSuccess(rootFile, file, response, chunk) {
},
//文件进度的回调
onFileProgress(rootFile, file, chunk) {
},
//出错
onFileError(rootFile, file, response, chunk) {
},
//上传列表缩放
fileListShow() {
this.collapse = !this.collapse;
let oDiv = document.getElementById('filePanel')
if(this.collapse){
//屏幕高度
let h = document.body.clientHeight ||
window.innerHeight ||
document.documentElement.clientHeight ;
//屏幕宽度
let w = document.body.clientWidth ||
window.innerWidth ||
document.documentElement.clientWidth ;
this.curTop = oDiv.style.top;
this.curLeft = oDiv.style.left
oDiv.style.top = (h-40) + "px";
oDiv.style.left = (w-170) + "px";
}else{
//回到原来的位置
oDiv.style.top = this.curTop ;
oDiv.style.left = this.curLeft;
}
},
//关闭上传列表
close() {
this.panelShow = false;
},
5、写了拖拽(不是必要)
directives: {
drag(el) {
let oDiv = el; //当前元素
let self = this; //上下文
//禁止选择网页上的文字
document.onselectstart = function() {
return false;
};
oDiv.onmousedown = function(e) {
//鼠标按下,计算当前元素距离可视区的距离
let disX = e.clientX - oDiv.offsetLeft;
let disY = e.clientY - oDiv.offsetTop;
document.onmousemove = function(e) {
//通过事件委托,计算移动的距离
let l = e.clientX - disX;
let t = e.clientY - disY;
//屏幕高度
let h = document.body.clientHeight ||
window.innerHeight ||
document.documentElement.clientHeight ;
//屏幕宽度
let w = document.body.clientWidth ||
window.innerWidth ||
document.documentElement.clientWidth ;
//左边菜单伸缩状态的宽度 图简单直接写了数字 严谨的小伙伴可以直接获取侧菜单的宽度
let leftBar = Cookies.get('sidebarStatus') == '0' ? 54 : 210
//判断有没有超过边界点
if (l > (w - oDiv.offsetWidth)) l = w - oDiv.offsetWidth;
if(l < leftBar) l = leftBar;
if (t > (h - oDiv.offsetHeight)) t = h - oDiv.offsetHeight;
if (t < 50) t = 50;
//移动当前元素
oDiv.style.left = l + "px";
oDiv.style.top = t + "px";
};
document.onmouseup = function(e) {
document.onmousemove = null;
document.onmouseup = null;
};
//return false不加的话可能导致黏连,就是拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
return false;
};
}
},
6、写的样式(当作参考抛砖引玉)
.uploader {
float: right;
.uploader-btn {
background: #f5921f;
color: #fff;
height: 30px;
font-weight: normal;
line-height: 24px;
border: 0px;
font-size: 12px;
}
.uploader-btn:hover {
background: #ebae67;
}
}
.file-panel {
position: fixed;
bottom: 10px;
right: 10px;
background: #fff;
box-shadow: 1px 1px 5px #ccc;
border-radius: 5px;
z-index: 2;
width: 650px;
height: 340px;
.file-title {
border: 1px solid #cccccc4a;
font-size: 10px;
height: 40px;
line-height: 40px;
padding-left: 10px;
h2 {
margin: 0px;
display: inline-block;
font-weight: normal;
color: #666363;
}
.operate {
float: right;
margin-right: 10px;
}
}
.file-list {
list-style-type: none;
height: 300px;
overflow-y: scroll;
padding: 0px;
margin: 0px;
width: 100%;
.uploader-file-info i {
display: none;
}
}
}
.mini {
right: -490px;
bottom: -306px;
.operate {
margin-right: 500px !important ;
}
}
/************************分割线***************************/
鉴于一些小伙伴说query传参数仍传递不了,以及以上demo进行上传的时候需要点击而不是选择文件以后立刻自动上传的问题。
小伙伴可以下载以下链接代码进行参考,里面有现成例子。
https://github.com/simple-uploader/Uploader
版权声明:本文为outlierQiqi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。