项目体验链接:term.mphy.me
关于
前几天图发奇想,想写一个 mini terminal,作为新手来学习和实践 Vue3 还是很好的。于是搜了一下 Github 上的开源项目,确实有,但都只是实现了一些很基本的输入输出,也就是说没有 mkdir、touch、ls、pwd 命令。
这里无意混淆大家 terminal、shell、kernel 的概念,只是为了简化项目描述,把这些指令也纳入 terminal 里了,详细的区别可以自行搜索。
所以就想动手实现一下,核心思想是利用 M 叉树,模拟 Linux 的目录系统,实现了创建文件和目录、目录跳转等基本功能。
- 在线体验:term.mphy.me
- 源码:github.com/Hacker-C/vu…
技术栈
- Vue3(composition api + script setup) + TS + Vite
- Pinia(状态管理)
- unplugin-auto-import + unplugin-vue-components(组件和 API 的自动按需导入)
特性
- 实现了基本的 linux 命令:pwd、ls、mkdir、touch、cd、clear
- 窗口拖拽功能以及防止过度拖拽的指令
- 模拟 MacOS 的样式
页面初始化:可拖拽、移动、关闭终端窗口
清屏:
基本的 ls、pwd、mkdir、touch 指令:(更多指令欢迎探索和 PR)
原理
文件结构使用了 N 叉树的数据结构,依据这个结构,实现了包含但不限于 mdir、touch、cd 等命令,还可以实现 autojump、search 等命令,只要是能在真实物理机上的大部分和文件相关的命令,都能实现(有待完成)。
interface Directory {
id: number // id
name: string // 当前目录名称
files: string[] // 当前目录下的文件列表
directories: Directory[] // 当前目录下的子目录列表,同时也是指向子目录的指针
previous: Directory | null // 指向父目录的指针
}
例如,我设计了 previous 指针,指向它的父节点,这样就实现了 cd .. 命令:
// 模拟 cd ..
export const cdBack = () => {
if (uds().dir.previous) {
uds().dir = uds().dir.previous as Directory
}
}
又比如,一个暂未实现的命令,echo 123 > file.txt,即将 123 这串字符串输入到 file.txt 文件中,可以改造 files 数据结构为:
interface file {
name: string // 文件名
content: string // 文件内容
}
这样就可以实现文件的读写操作了。
总结
本文是 Vue3-Terminal 这个图发奇想的小 demo 的推广,希望帮助正在学习 Vue3 + TS 的小伙伴进一步熟悉知识点。同时,你也能学到数据结构与算法的相关知识。