当前位置: 首页 > Web前端 > HTML

xterm.js+react的综合使用(onKey和onData的不同导致的游标连环问题)

时间:2023-03-28 00:32:38 HTML

xterm.js官网参考学习案例1.准备npminstallxtermnpminstallxterm-addon-fit2.初步介绍renderingimport{Terminal}from'xterm'import{FitAddon}from'xterm-addon-fit'import'xterm/css/xterm.css'letterm=newTerminal({//渲染类型rendererType:'canvas',//是否禁用inputdisableStdin:false,cursorStyle:'underline',//启用时光标将设置为下一行的开头convertEol:true,//终端回滚量scrollback:10,fontSize:14,rows:20,//光标闪烁cursorBlink:true,theme:{//fontforeground:'#ffffff',background:'#000000',//cursorcursor:'help',lineHeight:18,},})//包装并输入开头的Symbol$term.prompt=()=>{term.write(`\r\n${terminalTitleTemplate}:`)}//适应容器元素大小letfitAddon=newFitAddon()term.loadAddon(fitAddon)fitAddon。fit()3.重点来了,使用onData可以输入中文按上下键使用history命令,光标不会连续覆盖之前的终端提示constkeyAction=(){//定义获取整行数据的变量letcurrentLineData=''//历史行输入数据lethistoryLineData=[]letlast=0//可以输入汉字term.onData(asynckey=>;{//enterkeyif(key.charCodeAt(0)===13){//添加行数据if(currentLineData!==''){//将当前行数据传入历史命令数组StorehistoryLineData.push(currentLineData)//定义当前行命令在整个数组中的位置last=historyLineData.length-1}//输入clear时清除终端内容if(currentLineData==='clear'){term.clear()}//这里可以发起请求传入整行数据//清除当前行数据currentLineData=''term.write(`\r\n${terminalTitleTemplate}:`)}elseif(key.charCodeAt(0)===127){//deletekey--》当当前行偏移x大于终端提示占用的位置时删除if(term._core.buffer.x>terminalTitleTemplate.length+1){currentLineData=currentLineData.slice(0,-1)term.write('\b\b')}}elseif(key==='\u001b[A'){//upkeyletlen=0if(historyLineData.length>0){len=historyLineData.length+1}if(last0){//当当前行有数据时,删除渲染时存储的历史数据for(leti=0;iterminalTitleTemplate.length+1){term.write('\b\b')}}lettext=historyLineData[last-1]术语。write(text)//关键点,记得存储当前行命令,保证下次上行或下行时,光标不会混淆覆盖终端提示currentLineData=textlast--}}elseif(key==='\u001b[B'){//downkeyletlent=0if(historyLineData.length>0){lent=historyLineData.length-1}if(last-1){for(leti=0;iterminalTitleTemplate.length+1){term.write('\b\b')}}让文本=historyLineData[last+1]term.write(text)currentLineData=textlast++}}else{//什么都不做的时候,输入currentLineData+=keyterm.write(key)}})}4.渲染执行useEffect(()=>;{//创建实例term.open(document.getElementById('ter'))//初始化term._initialized=trueterm.prompt()//适应容器元素大小term.loadAddon(fitAddon)fitAddon.fit()term.focus()keyAction()return()=>{term.dispose()}},[])return(<>{/*终端加载容器*/})题尾,我写这个的时候,因为游标是序列化的,使用up/down键时输出命令是序列化的,找了半天,还是没看懂它。最开始是用onKey监听键盘操作,onData用来保证汉字的粘贴输入。真是一团糟。后来发现直接onData监听输入就不会这样了,这个问题就不存在了。