Vue 3 Integration (Composition API)
Integrating Strelit UI Kit with Vue 3 is clean and natural using
<script setup> and Vue's built-in
<Teleport> or programmatic
createApp() mounting.
1. Installation
Install the Strelit UI Kit package in your Vue 3 project:
npm install strelit-ui-kit
2. Docking Workspace Component (`DockingWorkspace.vue`)
In Vue 3, we can use <Teleport> to project reactive Vue components
directly into the DOM containers created by Strelit Layout:
<script setup lang="ts">
import { ref, onMounted, onUnmounted, reactive } from 'vue';
import { StrelitLayout, LayoutConfig } from 'strelit-ui-kit';
import 'strelit-ui-kit/dist/css/strelit-base.css';
import 'strelit-ui-kit/dist/css/themes/strelit-dark-theme.css';
import TelemetryViewer from './TelemetryViewer.vue';
import LogStreamViewer from './LogStreamViewer.vue';
interface PortalSlot {
id: string;
target: HTMLElement;
type: 'telemetry' | 'logs';
}
const layoutContainer = ref<HTMLElement | null>(null);
let layoutInstance: StrelitLayout | null = null;
const activeSlots = reactive<PortalSlot[]>([]);
onMounted(() => {
if (!layoutContainer.value) return;
const config: LayoutConfig = {
content: [{
type: 'row',
content: [
{
type: 'component',
componentName: 'vuePortal',
title: 'Live Telemetry',
componentState: { slotType: 'telemetry', id: 'slot-telemetry' }
},
{
type: 'component',
componentName: 'vuePortal',
title: 'Event Stream',
componentState: { slotType: 'logs', id: 'slot-logs' }
}
]
}]
};
layoutInstance = new StrelitLayout(config, layoutContainer.value);
layoutInstance.registerComponent('vuePortal', (container, state) => {
const el = container.getElement()[0] || container.getElement();
activeSlots.push({
id: state.id,
target: el,
type: state.slotType
});
container.on('destroy', () => {
const idx = activeSlots.findIndex(s => s.id === state.id);
if (idx !== -1) activeSlots.splice(idx, 1);
});
});
layoutInstance.init();
window.addEventListener('resize', () => layoutInstance?.updateSize());
});
onUnmounted(() => {
layoutInstance?.destroy();
});
</script>
<template>
<div class="workspace-viewport">
<div ref="layoutContainer" class="layout-target"></div>
<!-- Teleport reactive Vue components into Strelit containers -->
<Teleport v-for="slot in activeSlots" :key="slot.id" :to="slot.target">
<TelemetryViewer v-if="slot.type === 'telemetry'" />
<LogStreamViewer v-else-if="slot.type === 'logs'" />
</Teleport>
</div>
</template>
<style scoped>
.workspace-viewport {
width: 100vw;
height: 100vh;
position: relative;
overflow: hidden;
}
.layout-target {
width: 100%;
height: 100%;
}
</style>
Benefits of Vue 3 Teleport Pattern
-
Preserved Reactivity: Pinia stores, Vue 3
ref, and computed properties continue updating without re-initialization. -
Scoped CSS: Scoped styles in your
.vuesingle-file components work without modification. - Clean Destruction: Removing panels from Strelit triggers standard Vue lifecycle cleanup.