做uniapp项目发布H5有个后台管理,用户说上传文件的体验需要改进,那个弹出选择文件对话框然后去填文件路径选择文件上传,感觉操作太麻烦,于是就有了这么一个需求,需要实现拖动文件直接上传的,这样效率和体验都比较好。
文章目录
- 使用场景
- 自定义组件
- 脚本实现
- 拖动文件
- 使用例子
- 使用组件
- 拖动上传
- 测试效果
使用场景
怎么实现呢,接下来研究自己电脑的资源管理器拖动文件效果,如下图所示,实现步骤大致讲一下,请想象一下被使用场景,需要给被使用者创建一个自定义组件<my-drag-files>
来用
自定义组件
然后,在自定义组件中加上一个子组件标签,为插槽<slot>
,由将来使用者加入被监听的子组件,代码如下
<template>
<view class="my-drag-files" id="my-drag-files">
<slot></slot>
</view>
</template>
<script>
//...
</script>
<style lang="scss">
.my-drag-files{
height: 100%;
}
</style>
脚本实现
实现自定义组件脚本,添加拖动文件监听,代码如下
export default {
name:"my-drag-files",
data() {
return { };
},
mounted() {
//添加监听
let elem = document.getElementById('my-drag-files');
elem.addEventListener('drop',this.ondrop,false);
elem.addEventListener('dragleave',this.ondropprevent);
elem.addEventListener('dragenter',this.ondropprevent);
elem.addEventListener('dragover',this.ondropprevent);
this.elem=elem;
},
// 销毁时
beforeUnmount(){
const { elem } = this;
//移除监听
elem.removeEventListener('drop',this.ondrop);
elem.removeEventListener('dragleave',this.ondropprevent);
elem.removeEventListener('dragenter',this.ondropprevent);
elem.removeEventListener('dragover',this.ondropprevent);
},
methods:{
//...
}
}
注意Vue开发版本,Vue2 用的是
beforeDestroy()
,Vue3用的beforeUnmount()
拖动文件
实现拖动事件方法ondrop(event)
,当拖动文件完成,会通过事件消息发出获取到的文件,交给将来使用者去实现
export default {
name:"my-drag-files",
//...
methods:{
ondrop(event){
this.ondropprevent(event);
this.$emit('drop',{
detail:{ files:event.dataTransfer.files },
currentTarget:{ dataset:{} }
});
},
ondropprevent(event){
event.stopPropagation();
event.preventDefault();
}
}
}
使用例子
使用组件
这样的自定义组件就算完成了,再看看将来使用者使用例子,在使用的自定义组件上需要添加一个监听事件方法ondrop
,代码如下
<template>
<view class="window-file-list">
<my-drag-files @drop='ondrop'>
<view class="column">
<view class="padding table-tr">
<!-- 列表头 -->
</view>
<scroll-view class="scroll-view expand" scroll-y="true">
<view class="padding">
<!-- 文件列表 -->
</view>
</scroll-view>
</view>
</my-drag-files>
</view>
</template>
<script>
//...
</script>
<style lang="scss">
//...
</style>
拖动上传
脚本中,添加监听事件方法ondrop(e)
,在里面实现文件上传就好
export default{
//...
methods:{
ondrop(e){
// console.log('ondrop',e)
const { files } = e.detail;
//...
uni.uploadFile({
url:'...',
//filePath:this.getTempFilePath(file[0]),
files,
success:(res)=>{
console.log('uploadFile',res);
}
});
},
getTempFilePath(file){
let path;
if(window.createObjectURL) path=window.createObjectURL(file);
else if(window.webkitURL) path=window.webkitURL.createObjectURL(file);
else if(window.URL) path=window.URL.createObjectURL(file);
else console.error('getTempFilePath has error');
return path;
}
}
}
其中添加的方法
getTempFilePath(file)
就是获取文件的临时文件路径的,如有需要,会用得上
测试效果
到此结束,试试看效果,代码写得没问题的话,从电脑桌面拖动文件到文件列表中试试,就会直接上传了。
注意,此项目实现的拖动文件上传功能只能在H5上用哦~