版本:"electron": "^13.6.9","vue-selecto": "^1.26.0"
先利用node的fs模块实现一个windows文件管理器的功能
用selecto实现文件扩选复制和拖拽移动的功能
渲染文件扩选
<div id="moveContent" class="container">
<vue-selecto
dragContainer=".elements"
v-bind:selectableTargets='[".selecto-area .cube"]'
v-bind:hitRate='100'
v-bind:selectByClick='true'
v-bind:selectFromInside='true'
v-bind:ratio='0'
@select="onSelect"
@selectEnd="selectEnd"
></vue-selecto>
<div v-if="isDisk">
<div style="width: 40%;float: left;padding: 0px 0px 10px 20px;" class="btn-bto-clz no-drag"
v-for="(item,index) in fileArr" @click="goDir(item)">
<div>({{item.mounted}})</div>
<el-progress :text-inside="true" :stroke-width="26" :percentage="item.capacity"></el-progress>
<div style="font-size: 14px;color: #999999">{{item.available}}可用,共{{item.total}}</div>
</div>
</div>
<div v-else-if="!isDisk" style="height: 70vh;overflow:scroll;-webkit-user-select: none;-webkit-app-region: none;" class="elements selecto-area" id="selecto1">
<div style="width: 40%;float: left;padding: 0px 0px 10px 5px;" v-for="(item,index) in fileArr"
class="btn-bto-clz no-drag cube" @click="goDir(item)" :id="item.path" draggable="true">
<i class="el-icon-document" v-if="item.type=='file'"></i>
<i class="el-icon-folder" v-if="item.type=='dir'"></i>
<span style="font-size: 14px;color: #333333;width: 35%">{{item.name}}</span>
</div>
</div>
</div>
import { VueSelecto } from 'vue-selecto'
components: {VueSelecto
},
onSelect (e) {
e.added.forEach(el => {
el.classList.add('selected')
})
e.removed.forEach(el => {
el.classList.remove('selected')
this.selected = []
})
},
selectEnd (e) {
e.selected.map(item => {
this.selected.push(item.id)
})
},
css
.container {
/*max-width: 800px;*/
}
.cube {
display: inline-block;
border-radius: 5px;
width: 40px;
height: 40px;
margin: 4px;
background: #f1f1f1;
--color: #4af;
text-align: center;
line-height: 40px;
}
h1, .description {
text-align: center;
}
.elements {
margin-top: 40px;
border: 2px solid #eee;
}
.selecto-area {
padding: 20px;
}
#selecto1 .cube {
transition: all ease 0.2s;
}
.moveable #selecto1 .cube {
transition: none;
}
.selecto-area .selected {
color: #fff;
background: var(--color);
}
.empty.elements {
border: none;
}
实现鼠标右键功能
<div v-if="showMouse" id="mouseList" style="width: 50px;border: #333333 1px solid;position: fixed;background-color: #f1f1f1;border-radius: 5px;" :style="{'top':mouseObj.y+'px','left':mouseObj.x+'px'}">
<div class="mouseItem no-drag" style="text-align: center;line-height: 40px;" id="copyMouse">复制</div>
<div class="mouseItem no-drag" style="text-align: center;line-height: 40px;" id="pasteMouse">粘贴</div>
<div class="mouseItem" style="text-align: center;line-height: 40px;">待续</div>
</div>
mounted () {
this.mouseInit()
fileMoveUtil.dropFile(this)
},
copyCli(){
window.sessionStorage.setItem('copyList', JSON.stringify(this.selected))
console.log(window.sessionStorage.getItem('copyList'))
},
pasteCli(){
let copyList=window.sessionStorage.getItem('copyList')
if(!copyList){
return
}
copyList=JSON.parse(copyList)
console.log(copyList)
for(let i=0;i<copyList.length;i++){
let name=copyList[i].split('\\')
fs.copyFileSync(copyList[i],this.dirPath+'\\'+name[name.length-1]);
}
},
reflushDir(){
//更新列表
fileUtil.getFiles(this)
},
mouseInit(){
let that=this
document.addEventListener('mousedown', (event)=>{
that.mouseObj=event
if(event.button == 2){
that.showMouse=false
that.showMouse=true
}else if(event.button == 0){
that.mouseHandle(that.mouseObj)
that.showMouse=false
}
})
},
ondragstart() {
for(let i=0;i<this.fileArr.length;i++){
let obj=document.getElementById(this.fileArr[i].path)
if(obj){
obj.ondragstart = (event) => {
event.preventDefault()
ipcRenderer.send('dragStart', this.fileArr[i].path)
}
}
}
},
mouseHandle(mouseObj){
if('copyMouse'===mouseObj.target.id){
this.copyCli()
}else if('pasteMouse'===mouseObj.target.id){
this.pasteCli()
this.reflushDir()
}
},
鼠标右键的选项不能用click事件,也不能用鼠标enter事件,所有使用mouseObj.target.id分别处理
获取文件列表工具方法,里面就初始化拖拽响应,
核心使用fs.copyFileSync(org,target)实现文件复制
async getFiles(that){
that.fileArr=[]
await fileHandleUtil.getDirByPath(that.dirPath,(err, files)=>{
if(err){
console.log('err',err)
}
if(!files){
return;
}
console.log(that.dirPath,files)
for(let i=0;i<files.length;i++){
let pa=''
if(that.dirPath.endsWith('\\')){
pa=that.dirPath+files[i]
}else{
pa=that.dirPath+'\\'+files[i]
}
fileHandleUtil.getFileStat(pa,(stats)=>{
if(stats){
let param={
'name':files[i],
'path':pa
}
if(stats.isFile()){
param.type='file'
}else if(stats.isDirectory()){
param.type='dir'
}
that.fileArr.push(param)
//初始化拖拽下载监听对象
that.$nextTick(()=>{that.ondragstart()})
}
})
}
console.log(that.fileArr)
})
},
dropFile(that){
const dragWrapper = document.getElementById("moveContent");
//添加拖拽事件监听器
dragWrapper.addEventListener("drop", (e) => {
//阻止默认行为
e.preventDefault();
//获取文件列表
const files = e.dataTransfer.files;
if(files && files.length > 0) {
//获取文件路径
let file=files[0]
let addr=file.path
if(addr.indexOf('src\main')<1){
let arr=addr.split(':')
addr=arr[0].substr(arr[0].length-1,1)+':'+arr[1]
}
console.log(addr+"-----"+e.target.id+'/'+file.name)
fs.copyFileSync(addr,e.target.id+'/'+file.name)
}
})
//阻止拖拽结束事件默认行为
dragWrapper.addEventListener("dragover", (e) => {
e.preventDefault();
})
},