前言
本项目是为开发一套容器化的开发、运行、测试环境,用以支持Web开发、程序设计等课程的实验教学。
完善现有文件管理器
现有的文件管理器只实现了基本的样式,以及鼠标右键可以添加新文件,但是鼠标右键唤出的菜单栏是固定位置。因此需要进一步完善,首先更改文件列表的样式,实现文件夹与文本文件的区分;另外实现鼠标右键可以创建文件夹、创建文件、重命名、删除文件、删除文件夹等操作。
定义文件类型枚举和节点类型接口
enum FileType {
folder,
ts,
js,
html,
css
}
interface Tree {
id: string
name: string
type: FileType
children?: Tree[]
}
给文件夹和文本文件分别添加图标
<el-tree-v2 ref="treeRef" :data="data" :props="props" :filter-method="filterMethod" :height="720"
node-key="id" @node-contextmenu="visible = true">
<template #default="{ node, data }">
<el-icon>
<folder v-if="data.type == FileType.folder"></folder>
<document v-else></document>
</el-icon>
<span>{{ node.label }}</span>
</template>
</el-tree-v2>
import { Folder, Document } from '@element-plus/icons-vue';
效果如下
修改鼠标右键点击位置
<el-tree-v2 ref="treeRef" :data="data" :props="props" :filter-method="filterMethod" :height="720" node-key="id"
@node-contextmenu="RightClick">
<template #default="{ node, data }">
<el-icon>
<folder v-if="data.type == FileType.folder"></folder>
<document v-else></document>
</el-icon>
<span>{{ node.label }}</span>
</template>
</el-tree-v2>
<el-card v-show="visible" id="menu" shadow="always">
<div>
<el-button type="text" @click="AddFoloder()" v-show="targetNode?.type==FileType.folder">add new folder</el-button>
</div>
<div>
<el-button type="text" @click="AddFile()" v-show="targetNode?.type==FileType.folder">add new file</el-button>
</div>
<div>
<el-button type="text" @click="Delete()">delete</el-button>
</div>
<div>
<el-button type="text" @click="Rename()">rename</el-button>
</div>
</el-card>
添加监听器
const RightClick = function (e: Event, data: Tree, node: TreeNode) {
visible.value = true;
let menu = document.querySelector("#menu");
if (menu)
menu.style.cssText = "position: fixed; left: " + (e.clientX) + 'px' + "; top: " + (e.clientY) + 'px; z-index: 999; cursor:pointer;';
document.addEventListener('click', cancelRightClick)
}
const cancelRightClick = function () {
visible.value = false;
document.removeEventListener('click', cancelRightClick);
}
效果如图
实现创建新文件、删除、重命名等功能
创建空文件夹
const AddFoloder = () => {
ElMessageBox.prompt('Please input folder', 'Add new folder', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
inputPattern:
/[\w!#$%&'*+/=?^_`{|}~-]?/,
inputErrorMessage: 'Please input folder',
})
.then(({ value }) => {
targetData.value!.children.push({
id: `${totalId.value++}`,
name: value,
type: FileType.folder,
children: []
})
data.value = [...data.value]
// ElMessage({
// type: 'success',
// message: `Your folder is:${value}`,
// })
})
.catch(() => {
})
}
创建新文件
const AddFile = () => {
ElMessageBox.prompt('Please input folder of file(name.type)', 'Add new file', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
inputPattern:
/[\w!#$%&'*+/=?^_`{|}~-]+(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
inputErrorMessage: 'Please input file(name.type)',
})
.then(({ value }) => {
const val = value.split(".");
let type = val[val.length - 1];
let fileType = fileTypes(type);
if (fileType != undefined) {
targetData.value!.children.push({
id: `${totalId.value++}`,
name: value,
type: fileType,
children: []
})
data.value = [...data.value]
} else {
ElMessage({
type: 'error',
message: `not support this type`,
})
}
// ElMessage({
// type: 'success',
// message: `Your file is:${value}`,
// })
})
.catch(() => {
})
}
删除文件和文件夹
const Delete = function () {
ElMessageBox.confirm('You will delete the file,continue?', 'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
})
.then(() => {
const parent = targetNode.value?.parent
const children: Tree[] = parent?.data.children || parent?.data
const index = children.findIndex((d) => d.id === targetData.value?.id)
children.splice(index, 1)
data.value = [...data.value]
})
.catch(() => {
})
}
重命名
const Rename = function () {
const isFolder = targetData.value?.type === FileType.folder;
ElMessageBox.prompt('Please input new name', 'Rename', {
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
inputPattern: isFolder
? /[\w!#$%&'*+/=?^_`{|}~-]?/ : /[\w!#$%&'*+/=?^_`{|}~-]+(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/,
inputErrorMessage: 'Please input correct name',
})
.then(({ value }) => {
let fileType;
if (!isFolder) {
const val = value.split(".");
let type = val[val.length - 1];
fileType = fileTypes(type);
} else
fileType = FileType.folder;
if (fileType != undefined) {
targetData.value!.name=value;
data.value = [...data.value]
} else {
ElMessage({
type: 'error',
message: `not support this type`,
})
}
// ElMessage({
// type: 'success',
// message: `Your folder is:${value}`,
// })
})
.catch(() => {
})
}