59 lines
1.2 KiB
Vue
59 lines
1.2 KiB
Vue
|
<template>
|
||
|
<div ref="renderEl"></div>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
import 'xterm/css/xterm.css'
|
||
|
import { Terminal } from 'xterm'
|
||
|
import { AttachAddon } from 'xterm-addon-attach'
|
||
|
import { onMounted, ref } from 'vue'
|
||
|
import { FitAddon } from 'xterm-addon-fit'
|
||
|
|
||
|
export default {
|
||
|
name: 'WsTerm',
|
||
|
|
||
|
props: {
|
||
|
container: String,
|
||
|
session: String
|
||
|
},
|
||
|
|
||
|
setup (props) {
|
||
|
const socket = new WebSocket(`ws://localhost:1234/ws/${props.container}/${props.session}`)
|
||
|
|
||
|
const renderEl = ref(null)
|
||
|
const term = new Terminal()
|
||
|
const attachAddon = new AttachAddon(socket)
|
||
|
const fitAddon = new FitAddon()
|
||
|
|
||
|
term.loadAddon(fitAddon)
|
||
|
term.loadAddon(attachAddon)
|
||
|
|
||
|
const resize = () => {
|
||
|
fitAddon.fit()
|
||
|
|
||
|
fetch(`http://localhost:1234/containers/${props.container}/${props.session}/resize`, {
|
||
|
method: 'post',
|
||
|
headers: { 'content-type': 'application/json' },
|
||
|
body: JSON.stringify({
|
||
|
cols: term.cols,
|
||
|
rows: term.rows
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
onMounted(() => {
|
||
|
const resizeObserver = new ResizeObserver(() => {
|
||
|
resize()
|
||
|
})
|
||
|
|
||
|
resizeObserver.observe(renderEl.value)
|
||
|
term.open(renderEl.value)
|
||
|
|
||
|
resize()
|
||
|
})
|
||
|
|
||
|
return { renderEl }
|
||
|
}
|
||
|
}
|
||
|
</script>
|