const debounce = (fn: Function, delay: number): Function => {
let timer: NodeJS.Timeout | null = null
return (...args: any[]) => {
if (timer) {
clearInterval(timer)
}
timer = setTimeout(() => {
fn(...args)
}, delay)
}
}
const updateSize = () => {
if (!dashboard.value)
return;
dashboard.value.style.width = `${props.defaultWidth}px`;
dashboard.value.style.height = `${props.defaultHeight}px`;
}
const updateScale = () => {
if (!container.value || !dashboard.value)
return;
const containerWidth = container.value.clientWidth;
const containerHeight = container.value.clientHeight;
const widthScale = containerWidth / props.defaultWidth;
const heightScale = containerHeight / props.defaultHeight;
const scale = Math.min(widthScale, heightScale);
const marginLeft = (containerWidth - props.defaultWidth * scale) / 2;
const marginTop = (containerHeight - props.defaultHeight * scale) / 2;
dashboard.value.style.margin = `${marginTop}px ${marginLeft}px`;
dashboard.value.style.transform = `scale(${scale})`;
}
const onResize = debounce(async () => {
updateSize();
updateScale();
}, 100);
const observer = new ResizeObserver(() => {
onResize();
});
const init = () => {
updateScale();
updateSize();
}
onMounted(() => {
init();
nextTick(async () => {
observer.observe(container.value!)
});
});
onUnmounted(() => {
observer.disconnect();
});
</script>
<template>
<div ref="container" class="container">
<div ref="dashboard" class="dashboard">
<slot></slot>
</div>
</div>
</template>
<style scoped lang="less">
.container {
width: 100%;
height: 100%;
overflow: hidden;
}
.dashboard {
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 500ms;
transform-origin: top left;
}
</style>
使用
import DashboardContainer from "@/module/DashBoardContainer/index.vue";//引入
<DashboardContainer ref="mainRef" style="width: 100%; height: 100%">
//需要自适应的地方
</DashboardContainer>