Vue Integration

// @cadview/vue โ€” Vue 3 component and composable

Installation

pnpm add @cadview/core @cadview/vue

CadViewer Component

<template>
	<input type="file" accept=".dxf" @change="onFileChange" />
	<CadViewer
		:file="file"
		theme="dark"
		tool="pan"
		@select="(e) => console.log(e.entity)"
		@measure="(e) => console.log(e.distance)"
		class="viewer"
	/>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { CadViewer } from '@cadview/vue';

const file = ref<File | null>(null);

function onFileChange(e: Event) {
	const input = e.target as HTMLInputElement;
	file.value = input.files?.[0] ?? null;
}
</script>

<style scoped>
.viewer {
	width: 100%;
	height: 600px;
}
</style>

Props

PropTypeDefault
fileFile \| ArrayBuffer \| string \| nullnull
themeTheme'dark'
toolTool'pan'
debugboolean \| DebugOptionsfalse
workerbooleanfalse
optionsCadViewerOptions{}
formatConvertersFormatConverter[][]

Events

EventPayloadDescription
selectSelectEventEntity clicked with select tool
measureMeasureEventTwo-point measurement completed
viewchangeViewTransformCamera position/zoom changed
layers-loadedDxfLayer[]Layers parsed from document

Template Ref

Access imperative methods via template ref:

<template>
	<CadViewer ref="viewerRef" :file="file" />
	<button @click="viewerRef?.fitToView()">Fit to View</button>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { CadViewer } from '@cadview/vue';

const viewerRef = ref<InstanceType<typeof CadViewer> | null>(null);
const file = ref<File | null>(null);
</script>

Exposed Methods

MethodReturnsDescription
getViewer()CadViewer \| nullAccess the core viewer instance
fitToView()voidFit camera to drawing extents
getLayers()DxfLayer[]Get all layers
setLayerVisible(name, visible)voidToggle layer visibility

useCadViewer Composable

For full control, use the composable with your own canvas:

<template>
	<canvas ref="canvasRef" class="cad-canvas" />
	<button @click="fitToView" :disabled="!isLoaded">Fit</button>
	<p v-if="isLoaded">{{ layers.length }} layers loaded</p>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { useCadViewer } from '@cadview/vue';

const canvasRef = ref<HTMLCanvasElement | null>(null);
const { viewer, layers, isLoaded, loadFile, fitToView, setTheme, setTool, setLayerVisible } =
	useCadViewer(canvasRef, { theme: 'dark' });
</script>

<style scoped>
.cad-canvas {
	width: 100%;
	height: 500px;
}
</style>

Composable Return Values

PropertyTypeDescription
viewerRef<CadViewer \| null>Core viewer instance
layersRef<DxfLayer[]>Current layers (reactive)
isLoadedRef<boolean>Whether a document is loaded
loadFile(file: File) => Promise<void>Load a File object
loadBuffer(buffer: ArrayBuffer) => Promise<void>Load an ArrayBuffer
loadString(dxf: string) => voidLoad a DXF string
fitToView() => voidFit camera to drawing
setLayerVisible(name: string, visible: boolean) => voidToggle layer
setTheme(theme: Theme) => voidChange theme
setTool(tool: Tool) => voidChange active tool

Full Example

<template>
	<div class="app">
		<header>
			<input type="file" accept=".dxf,.dwg" @change="onFileChange" />

			<select v-model="tool" @change="onToolChange">
				<option value="pan">Pan</option>
				<option value="select">Select</option>
				<option value="measure">Measure</option>
			</select>

			<button @click="viewerRef?.fitToView()">Fit</button>
		</header>

		<CadViewer
			ref="viewerRef"
			:file="file"
			:tool="tool"
			theme="dark"
			:format-converters="[dwgConverter]"
			@select="onSelect"
			@measure="(e) => console.log('Distance:', e.distance)"
			@layers-loaded="(l) => (layers = l)"
			class="viewer"
		/>

		<p v-if="selected">Selected: {{ selected }}</p>

		<aside>
			<h3>Layers</h3>
			<label v-for="layer in layers" :key="layer.name">
				<input
					type="checkbox"
					:checked="!layer.isOff"
					@change="
						viewerRef?.setLayerVisible(layer.name, ($event.target as HTMLInputElement).checked)
					"
				/>
				{{ layer.name }}
			</label>
		</aside>
	</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { CadViewer, type DxfLayer, type SelectEvent } from '@cadview/vue';
import { dwgConverter } from '@cadview/dwg';

const viewerRef = ref<InstanceType<typeof CadViewer> | null>(null);
const file = ref<File | null>(null);
const tool = ref<'pan' | 'select' | 'measure'>('pan');
const layers = ref<DxfLayer[]>([]);
const selected = ref<string | null>(null);

function onFileChange(e: Event) {
	const input = e.target as HTMLInputElement;
	file.value = input.files?.[0] ?? null;
}

function onSelect(event: SelectEvent) {
	selected.value = `${event.entity.type} on layer "${event.entity.layer}"`;
}

function onToolChange() {
	// tool is reactive via v-model
}
</script>

<style scoped>
.viewer {
	width: 100%;
	height: 80vh;
}
</style>