引言
因为最近项目需要写一个网页版终端,然而网上资料很多,但发现相关配置和API都很少,而且官网文档也很难看懂,因此小编翻阅了核心的源码,实现了一版,在此分享给各位码农。本篇文章将尽可能全面的罗列出xterm的配置和API。
1. 环境搭建
本文将针对如下版本的依赖进行说明:
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
2. 初始化xterm.js
<template>
<div class="terminalPage">
<div class="terminal" ref="terminalDiv"></div>
</div>
</template>
<script>
import * as xterm from 'xterm';
import 'xterm/css/xterm.css';
import { FitAddon } from 'xterm-addon-fit'; // 横向自适应
export default {
name: 'terminal',
data() {
return {
xterm: null,
fitAddon: null,
ws: null,
commandBuffer: ''
}
},
mounted() {
this.initTerminal();
},
methods: {
initTerminal() {
this.xterm = new xterm.Terminal({
rows: 30, // 可视窗口的行数
cols: 80, // 可是窗口的列数
cursorBlink: true, // 光标是否闪烁
// 终端主题
theme: {
foreground: '#ffffff',
background: '#000000'
cursor: '#ffffff',
},
fontFamily: 'Consolas, Courier, monospace',
fontSize: 14,
});
this.xterm.open(this.$refs.terminalDiv);
this.fitAddon = new FitAddon();
this.xterm.loadAddon(this.fitAddon);
this.fitAddon.fit();
window.addEventListener('resize', () => {
try {
this.fitAddon.fit();
} catch (e) {
this.$message.error(e.message);
}
});
this.xterm.write('Connecting \r\n');
this.xterm.onData((data) => this.terminalOnData(data));
this.xterm.onKey((event) => this.terminalOnKey(event));
},
}
}
</script>
3. 使用onData监听输入并在终端中实时显示
methods: {
terminalOnData(data) {
this.term.write(data);
this.commandBuffer += data;
}
}
4. 使用onKey处理键盘的快捷键操作
methods: {
terminalOnKey(event) {
const { domEvent } = event;
const ctrlKey = this.checkCtrlKeyAllSystem(domEvent); // 是否按了Ctrl键
// 回车键
if (event.domEvent.key === 'Enter') {
// 发送命令
this.ws.send(this.commandBuffer);
this.commandBuffer = '';
// Tab键
} else if (event.domEvent.key === 'Tab') {
// tab补全...
}
// Backspace退格键或Delete删除键
} else if (event.domEvent.key === 'Backspace' || event.domEvent.key === 'Delete') {
// 在终端中模拟删除效果
this.xterm.write('\b \b');
// 上箭头
} else if (event.domEvent.key === 'ArrowUp') {
// 历史指令...
}
// 下箭头
} else if (event.domEvent.key === 'ArrowDown') {
// 历史指令...
// Ctrl+C 快捷键
} else if (ctrlKey && event.domEvent.key === 'c') {
// ...
}
// Ctrl+Shift+A 快捷键
} else if (ctrlKey && domEvent.shiftKey && event.domEvent.key === 'a') {
// ...
}
// 其他按键与快捷键等处理...
// ...
} else {
this.term.write(key)
}
}
// 判断是否按了Ctrl键 - 兼容Mac和Win不同系统
checkCtrlKeyAllSystem(domEvent) {
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
const isPressCtrlKey = isMac ? domEvent.metaKey : domEvent.ctrlKey;
return isPressCtrlKey;
},
}
5. 使用WebSocket连接至服务器
mounted() {
this.initSocket();
},
methods: {
initSocket() {
this.ws = new WebSocket('ws://192.168.1.1:8080/websocket/terminal')
this.ws.onopen = this.socketOnOpen;
this.ws.onmessage = this.socketOnMessage;
this.ws.onclose = this.socketOnClose;
this.ws.onerror = this.socketOnError;
},
socketOnOpen() {
this.xterm.write('连接成功');
},
socketOnMessage(event) {
console.log('收到消息