縮放與置中 API
僅限 comp-hub
$onScaleChange 是由 comp-hub 的預覽環境注入的。它不是標準框架 API,在 comp-hub 之外不存在。對於 Vue 元件,它被新增到 Vue 實例(this.$onScaleChange);對於 React 元件,它作為 prop onScaleChange 傳入。如果您在元件中使用此 API,請確保在 comp-hub 之外執行時對其為 undefined 的情況進行防護。
$onScaleChange 訂閱容器尺寸變化並自動計算縮放與置中樣式,協助內容適應預覽容器。
為什麼需要縮放?
迷你預覽面板空間有限(通常約 300×200),但有些元件會顯示豐富的內容(圖表、表格、複雜表單佈局等)。如果不縮放,迷你面板中只能看到部分區域,無法查看完整元件。縮放 API 讓您可以定義預設的內容尺寸(例如 800×500),並自動將其縮放以適應迷你容器,保持所有內容可見。
ts
type ScaleMode = "widthFirst" | "heightFirst" | "contain" | "cover"
interface ScaleStyle {
transform: string // e.g. "translate(100px, 50px) scale(0.75)"
transformOrigin: string // always "left top"
}縮放模式
| 模式 | 行為 |
|---|---|
"widthFirst" | 縮放以適應容器寬度,高度可能溢出 |
"heightFirst" | 縮放以適應容器高度,寬度可能溢出 |
"contain" | 等比縮放,內容完全可見於容器內(建議預設) |
"cover" | 等比縮放,內容填滿容器(可能裁剪多餘部分) |
所有模式都會透過 translate 將內容在容器內置中。
$onScaleChange(params, callback) → 取消訂閱
訂閱容器尺寸變化。回呼會立即以目前的縮放值被呼叫,之後每次容器調整大小時再次呼叫。
ts
const unsubscribe = this.$onScaleChange(
params: { mode: ScaleMode, width: number, height: number },
callback: (style: ScaleStyle) => void
): () => void使用(React)
縮放 API 的 React 版本作為 prop onScaleChange 傳給您的 demo 元件:
jsx
import React, { useEffect, useState } from "react";
const DemoMini = ({ onScaleChange }) => {
const [scaleStyle, setScaleStyle] = useState({});
useEffect(() => {
if (onScaleChange) {
const unsubscribe = onScaleChange(
{ mode: "contain", width: 800, height: 500 },
(style) => setScaleStyle(style)
);
return unsubscribe; // cleanup on unmount
}
}, [onScaleChange]);
return (
<div style={scaleStyle}>
{/* your content */}
</div>
);
};
export default DemoMini;使用(Vue 2 Options API)
vue
<script>
export default {
data() {
return { scaleStyle: {} }
},
mounted() {
// 訂閱 — 容器調整大小時自動重新計算
this._unsub = this.$onScaleChange(
{ mode: "contain", width: 800, height: 500 },
(style) => { this.scaleStyle = style }
)
},
beforeDestroy() {
this._unsub?.() // 清理訂閱
}
}
</script>使用(Vue 3 Composition API)
vue
<script setup>
import { ref, getCurrentInstance, onBeforeUnmount } from "vue"
const instance = getCurrentInstance()
const scaleStyle = ref({})
const unsub = instance.proxy.$onScaleChange(
{ mode: "contain", width: 800, height: 500 },
(style) => { scaleStyle.value = style }
)
onBeforeUnmount(() => unsub())
</script>常見模式
固定內容尺寸的 Demo 元件
預覽 demo 元件通常宣告一個固定的內容區域,然後使用縮放 API 來填滿預覽面板:
vue
<template>
<div class="demo-wrapper" :style="scaleStyle">
<!-- 以 800×500 設計的內容 -->
<div class="demo-content">...</div>
</div>
</template>
<script>
export default {
data() {
return { scaleStyle: {} }
},
mounted() {
this._unsub = this.$onScaleChange(
{ mode: "contain", width: 800, height: 500 },
(style) => { this.scaleStyle = style }
)
},
beforeDestroy() {
this._unsub?.()
}
}
</script>
<style scoped>
.demo-wrapper {
transform-origin: left top;
}
.demo-content {
width: 800px;
height: 500px;
overflow: hidden;
}
</style>最佳實務
- 清理訂閱 — 務必在
beforeDestroy/onBeforeUnmount中呼叫unsubscribe()以防止記憶體洩漏 - 固定內容尺寸 — 以特定的寬 × 高(例如 800×500)設計您的 demo,讓縮放 API 處理其餘部分
contain是安全的預設 — 即使在小型面板中也能確保所有內容可見- 為非 comp-hub 環境做防護 — 由於此 API 僅存在於 comp-hub 預覽中,呼叫前務必檢查其是否可用:
js
// 安全呼叫模式
if (this.$onScaleChange) {
this._unsub = this.$onScaleChange(
{ mode: "contain", width: 800, height: 500 },
(style) => { this.scaleStyle = style }
)
}