template部分
<template><div class="canvas-wrapper" ref="canvasWrapper"><svg:viewBox="computedViewBox"ref="svgCanvas"xmlns="http://www.w3.org/2000/svg"xmlns:xlink="http://www.w3.org/1999/xlink"class="schematic-svg"@mousedown="startDrag"@mousemove="onDrag"@mouseup="endDrag"@wheel="onScroll"v-html="svgContent"preserveAspectRatio="xMinYMin meet"></svg></div>
</template>
this.klFile = "data:image/svg+xml;base64," + data[0].kl_svg
<svg-component v-if="klFile !== null" :svg-base64="klFile" view-box="0 0 2000 2000"></svg-component>
script部分
<script>
export default {name:'SvgComponent',props: {svgBase64: {type: String,required: true},viewBox: {type: String,required: true},},data() {return {computedViewBox: this.viewBox, // 用于动态修改的 viewBoxdragging: false,startX: 0,startY: 0,viewBoxX: 0,viewBoxY: 0,svgContent: "", // 存储解码后的 SVG 内容};},watch: {svgBase64() {// 响应 props 变化并重新渲染 SVGthis.decodeSvgBase64();},},mounted() {this.decodeSvgBase64();},methods: {decodeSvgBase64() {// 解码 Base64 数据// 检查并移除可能存在的 Base64 数据头let base64String = this.svgBase64;const prefix = "data:image/svg+xml;base64,";if (base64String.startsWith(prefix)) {base64String = base64String.replace(prefix, "");}// 尝试解码 Base64 数据const decodedData = atob(base64String);this.svgContent = decodedData; // 将解码后的内容赋值给 svgContent},startDrag(event) {this.dragging = true;this.startX = event.clientX;this.startY = event.clientY;},onDrag(event) {if (this.dragging) {const dx = this.startX - event.clientX;const dy = this.startY - event.clientY;this.viewBoxX += dx;this.viewBoxY += dy;this.updateViewBox();this.startX = event.clientX;this.startY = event.clientY;}},endDrag() {this.dragging = false;},onScroll(event) {event.preventDefault();const zoomAmount = 1.1;const [x, y, w, h] = this.computedViewBox.split(" ").map(Number);// Zoom in or outif (event.deltaY < 0) {// Zoom inthis.computedViewBox = `${x + w * (1 - 1 / zoomAmount) / 2} ${y + h * (1 - 1 / zoomAmount) / 2} ${w / zoomAmount} ${h / zoomAmount}`;} else {// Zoom outthis.computedViewBox = `${x - w * (zoomAmount - 1) / 2} ${y - h * (zoomAmount - 1) / 2} ${w * zoomAmount} ${h * zoomAmount}`;}},updateViewBox() {const [x, y, w, h] = this.viewBox.split(" ").map(Number);this.computedViewBox = `${this.viewBoxX} ${this.viewBoxY} ${w} ${h}`;}},
};
</script>
css部分
<style scoped>
.canvas-wrapper {border-radius: 10px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);overflow: hidden;
}.schematic-svg {width: 100%;height: 100%;
}
</style>