- 一键切换「整体 Scale 缩放」「Rem 等分适配」
- 窗口自动监听 resize
- 适配设计稿 1920*1080
- Vue3 全局直接引入用
一、新建组件 ScreenAdapter.vue
xml
<template>
<div class="screen-adapter" :class="{ 'scale-mode': type === 'scale' }">
<!-- 大屏所有内容插槽 -->
<slot />
</div>
</template>
<script setup>
import { onMounted, onUnmounted } from 'vue';
const props = defineProps({
// 适配模式:scale / rem
type: {
type: String,
default: 'scale', // 默认用不变形的scale
validator: val => ['scale', 'rem'].includes(val)
},
// 设计稿宽高
designWidth: {
type: Number,
default: 1920
},
designHeight: {
type: Number,
default: 1080
}
});
let resizeFn = null;
// 1. Scale 整体缩放适配
function initScale() {
const wrap = document.querySelector('.screen-adapter');
if (!wrap) return;
const clientW = document.documentElement.clientWidth;
const clientH = document.documentElement.clientHeight;
const scaleW = clientW / props.designWidth;
const scaleH = clientH / props.designHeight;
const scale = Math.min(scaleW, scaleH);
wrap.style.transform = `translate(-50%, -50%) scale(${scale})`;
}
// 2. Rem 等分适配 设计稿px直接写rem
function initRem() {
const clientW = document.documentElement.clientWidth;
// 把屏幕分成100份 1rem = 1%屏幕宽
document.documentElement.style.fontSize = clientW / 100 + 'px';
}
// 初始化适配
function adapterInit() {
if (props.type === 'scale') {
initScale();
} else {
initRem();
}
}
onMounted(() => {
adapterInit();
resizeFn = adapterInit;
window.addEventListener('resize', resizeFn);
});
onUnmounted(() => {
window.removeEventListener('resize', resizeFn);
});
</script>
<style scoped>
html,
body {
margin: 0;
height: 100%;
overflow: hidden;
}
.screen-adapter {
position: fixed;
left: 50%;
top: 50%;
transform-origin: 0 0;
}
/* Scale模式固定画布大小 */
.scale-mode {
width: 1920px;
height: 1080px;
}
</style>
二、页面中使用
1. 用 Scale 模式(推荐交付、地图大屏、不变形)
xml
<template>
<!-- 只用包一层,内部全部按1920*1080写px即可 -->
<ScreenAdapter type="scale">
<!-- 你的大屏页面内容 -->
<div class="title">智慧公路大屏</div>
</ScreenAdapter>
</template>
<script setup>
import ScreenAdapter from '@/components/ScreenAdapter.vue';
</script>
<style>
.title {
/* 直接写px,不用任何换算 */
font-size: 36px;
width: 400px;
height: 80px;
line-height: 80px;
text-align: center;
}
</style>
2. 切换 Rem 模式(内部项目、铺满全屏)
ini
<ScreenAdapter type="rem">
内部大屏内容
</ScreenAdapter>
Rem 用法规则设计稿多少 px,直接写多少 rem:
- 设计稿 200px →
width: 200rem - 字体 28px →
font-size: 28rem不用计算、不用除以任何数。
三、两种模式使用场景记住
- type="scale"
- 对外交付、政府大屏、Mapbox/L7/GIS 地图
- 优点:不变形、像素级还原、适配所有屏
- 写法:全部写 px
- type="rem"
- 内部后台、运维大屏、工期紧
- 优点:全屏无留白、开发快
- 写法:设计稿 px 直接换成 rem
四、关键注意点
- Scale 模式下所有弹窗、ECharts、地图都要包在插槽里面,不要单独挂 body
- 不需要再写任何额外适配 JS,组件已经封装好监听 resize
- 以后所有大屏页面,直接套这个组件,改个 type 就能切换适配方案