效果

代码实现
import { defineComponent, onBeforeUnmount, onMounted, ref } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import './index.less'
export default defineComponent({
props: {
designWidth: {
type: Number,
default: 1920
},
designHeight: {
type: Number,
default: 1080
}
},
setup(props, { slots }) {
const scale = ref(1)
const { designHeight, designWidth } = props
const calcScale = () => {
const screenWidth = document.documentElement.clientWidth
const screenHeight = document.documentElement.clientHeight
let _scale =
screenWidth / screenHeight < designWidth / designHeight
? screenWidth / designWidth
: screenHeight / designHeight
scale.value = _scale
}
const debounceCalcScale = useDebounceFn(calcScale, 300)
onMounted(() => {
calcScale()
window.addEventListener('resize', debounceCalcScale)
})
onBeforeUnmount(() => {
window.removeEventListener('resize', debounceCalcScale)
})
return () => (
<div class="scale-view-wrapper">
<div
class="scale-view-screen"
style={{
width: `${designWidth}px`,
height: `${designHeight}px`,
transform: `scale(${scale.value}) translate(-50%)`
}}
>
{slots.default?.()}
</div>
</div>
)
}
})
.scale-view-wrapper {
height: 100vh;
width: 100vw;
position: relative;
overflow: hidden;
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
.scale-view-screen {
transform-origin: 0 0;
position: absolute;
left: 50%;
}
使用
import ScaleScreen from '@/components/ScaleScreen'
import styles from './index.module.less'
export default {
setup() {
return () => (
<ScaleScreen designHeight={1080} designWidth={1920}>
<div class={styles['wrapper']}>
<img
class={styles['bg']}
src={new URL('./static/lezhen-step1.png', import.meta.url).href}
/>
</div>
</ScaleScreen>
)
}
}