實務上會遇到很長的 Log 必須在 Xterm.js 顯示,且由於 Browser 的 RWD 特性,要如何讓 Xterm.js 能根據各種寬度改變是很大挑戰。
Version
Vue 3.0.11
Xterm.js 4.11.0
Add FitAddon
$ yarn add xterm-addon-fit
使用 Yarn 安裝 xterm-addont-fit。
Composition API
儘管 String 很長,會自動填滿 Xterm.js 所佔據寬度。
就算 resize browser,String 也會自動換行。
<template lang='pug'>
div(ref='xterm')
</template>
<script setup>
import { onMounted, onUnmounted } from 'vue'
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import 'xterm/css/xterm.css'
import 'xterm/lib/xterm.js'
ref: xterm = null
let terminal = new Terminal
let fitAddon = new FitAddon
let xtermFit = () => fitAddon.fit()
let mount = () => {
addEventListener('resize', xtermFit)
terminal.loadAddon(fitAddon)
terminal.open(xterm)
fitAddon.fit()
terminal.writeln('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem ea eligendi labore officia voluptatibus! Aliquam aut culpa ea nam natus porro praesentium quaerat quia quibusdam reiciendis, sapiente suscipit tempore ut?')
}
let unmount = () => removeEventListener('resize', xtermFit)
onMounted(mount)
onUnmounted(unmount)
</script>
21 行
terminal.loadAddon(fitAddon)
terminal.open(xterm)
fitAddon.fit()
- 使用
terminal.loadAddon()
載入 FitAddon - 在
terminal.open()
之後執行fitAddon.fit()
,會第一次根據目前 Xterm.js 寬度動態調整
25 行
terminal.writeln('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem ea eligendi labore officia voluptatibus! Aliquam aut culpa ea nam natus porro praesentium quaerat quia quibusdam reiciendis, sapiente suscipit tempore ut?')
使用 terminal.writeln()
顯示很長的 String。
terminal.write()
將無法 RWD,只能使用terminal.writeln()
20 行
addEventListener('resize', xtermFit)
另外一個要解決問題是 resize browser 時,該如何動態改變很長 String 顯示。
使用 addEventListener()
將 xternFit()
註冊到 resize
event。
16 行
let xtermFit = () => fitAddon.fit()
執行 fitAddon.fit()
根據目前 Xterm.js 寬度重新調整顯示。
28 行
let unmount = () => removeEventListener('resize', xtermFit)
由於在 onMounted
hook 註冊了 resize
event,別必須在 onUnmounted
hook 取消註冊 resize
event。
30 行
onMounted(mount)
onUnmounted(unmount)
onMounted()
:註冊onMounted
hookonUnmounted()
:註冊onUnmounted
hook
Point-free
結果不變,但使用 Point-free 改寫。
<template lang='pug'>
div(ref='xterm')
</template>
<script setup>
import { onMounted, onUnmounted } from 'vue'
import { pipe, always } from 'ramda'
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import 'xterm/css/xterm.css'
import 'xterm/lib/xterm.js'
ref: xterm = null
let terminal = new Terminal
let fitAddon = new FitAddon
let xtermFit = () => fitAddon.fit()
let mount = () => {
addEventListener('resize', xtermFit)
terminal.loadAddon(fitAddon)
terminal.open(xterm)
fitAddon.fit()
terminal.writeln('Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem ea eligendi labore officia voluptatibus! Aliquam aut culpa ea nam natus porro praesentium quaerat quia quibusdam reiciendis, sapiente suscipit tempore ut?')
}
let unmount = () => removeEventListener('resize', xtermFit)
pipe(
always(mount),
onMounted,
always(unmount),
onUnmounted
)()
</script>
31 行
pipe(
always(mount),
onMounted,
always(unmount),
onUnmounted
)()
使用 pipe()
組合 IIFE:
always(mount)
:準備mount()
傳入onMounted()
onMounted
:註冊onMounted
hookalways(unmount)
:準備unmount()
傳入到onUnmounted()
onUnmounted
:註冊onUnmounted
hook
Conclusion
- FitAddon 只能解決一開始寬度問題,必須在結合 resize event 再次執行 FitAddon 才能完美解決 RWD
- 只能使用
terminal.writeln()
,不能使用terminal.write()