如果 页面的自适应是 「大屏等比缩放方案」 —— 以 1920*1080(大屏设计稿通用尺寸)为基准,让页面在任意屏幕下按比例缩放,保证布局不变形。

  1. 核心:自定义缩放函数 scalePageFull
const scalePageFull = () => {
  // 1. 定义设计稿基准尺寸(你自己根据设计稿定,这里是1920*1080)
  const baseWidth = 1920; 
  const baseHeight = 1080;

  // 2. 计算「当前屏幕」与「设计稿」的缩放比例(原生API获取窗口尺寸)
  const scaleX = window.innerWidth / baseWidth; // 宽度方向缩放比(当前宽/设计稿宽)
  const scaleY = window.innerHeight / baseHeight; // 高度方向缩放比(当前高/设计稿高)

  // 3. 取最小缩放比,保证页面完整显示(等比缩放,不超出屏幕)
  const scale = Math.min(scaleX, scaleY);

  // 4. 获取你自定义的「缩放根容器」(模板里的scale-wrapper)
  const wrapper = document.getElementById("scale-wrapper");
  
  if (wrapper) {
    // 5. 核心:设置缩放样式(CSS内置属性)
    wrapper.style.transform = `scale(${scale}) translate(-50%, -50%)`; 
    // - scale(${scale}):按计算出的比例整体缩放容器
    // - translate(-50%, -50%):配合绝对定位让容器居中
    wrapper.style.transformOrigin = "top left"; // 缩放原点(左上角),保证缩放位置不偏移
    wrapper.style.position = "absolute"; // 绝对定位,让translate生效
    wrapper.style.left = "50%"; // 水平居中基准
    wrapper.style.top = "50%"; // 垂直居中基准
    wrapper.style.width = `${baseWidth}px`; // 容器宽度设为设计稿宽度
    wrapper.style.height = `${baseHeight}px`; // 容器高度设为设计稿高度
    wrapper.style.overflow = "hidden"; // 隐藏超出部分,避免滚动条
  }
};
  1. 性能优化:自定义防抖函数 debounce
    窗口resize事件(拖动窗口、切换屏幕)会高频触发(每秒几十次),如果每次都执行scalePageFull会卡顿,所以手写防抖函数限制执行频率:
const debounce = (fn: Function, delay = 200) => {
  let timer: number | null = null; // 自定义定时器标识
  return () => {
    if (timer) window.clearTimeout(timer); // 清除旧定时器(原生API)
    timer = window.setTimeout(() => fn(), delay); // 延迟执行目标函数(原生API)
  };
};
// 包装缩放函数,200ms内只执行最后一次
const handleResize = debounce(scalePageFull, 200);
  1. 生命周期管理(Vue3 内置 API + 自定义逻辑)
    组件挂载时初始化缩放,卸载时清理监听(避免内存泄漏):
onMounted(() => {
  scalePageFull(); // 组件挂载后,先执行一次缩放(初始化)
  window.addEventListener("resize", handleResize); // 监听窗口变化,触发防抖缩放
});

onUnmounted(() => {
  window.removeEventListener("resize", handleResize); // 组件卸载,移除监听(自定义逻辑)
});
  1. 模板支撑:自定义缩放容器
    所有页面内容都包在scale-wrapper里,缩放这个容器就等于缩放整个页面:
<div id="container">
  <div id="scale-wrapper"> <!-- 你自定义的缩放根容器 -->
    <!-- 所有页面内容(头部、卡片、底部等)都在这里 -->
  </div>
</div>

后续需要补:

学window对象:innerWidth/innerHeight(获取窗口尺寸)、addEventListener(监听事件); ✅
练习:写一个 HTML 文件,打印当前窗口尺寸,拖动窗口时实时打印;
学document对象:getElementById/querySelector(获取 DOM); ✅ 练习:获取一个 div,修改它的宽度
/ 高度样式; 学定时器:setTimeout/clearTimeout(防抖的基础); ✅ 练习:写一个函数,点击按钮后延迟 200ms
执行。

缩放后字体模糊:给transform加translateZ(0)开启硬件加速:
ts
wrapper.style.transform = scale(${scale}) translate(-50%, -50%) translateZ(0);

transform 里的多个属性是从右到左(从后到前) 执行的!
比如 transform: scale(0.8) translate(-50%, -50%),实际执行顺序是:
第一步:translate(-50%, -50%)(位移)→ 第二步:scale(0.8)(缩放)

scale(scale)的作用:等比缩放容器scale({scale}) 的作用:等比缩放容器 scale(scale)的作用:等比缩放容器scale({scale})是按计算出的比例(当前屏幕 / 设计稿 1920*1080)缩放整个容器,保证页面内容等比适配不同屏幕。

wrapper.style.position = “absolute” 的核心原因
设置position: absolute是让「居中 + 缩放」逻辑生效的前提,没有它,left/top/translate都会失效,拆解如下:

  1. 绝对定位(absolute)的核心特性
    absolute定位的元素会:
    脱离正常文档流,不会影响其他元素的布局;
    其left/top/right/bottom属性是相对于最近的已定位祖先元素(这里是#container,因为#container是默认的 static,但absolute会向上找直到视口);
    只有定位元素(absolute/fixed/relative/sticky)的left/top/right/bottom属性才会生效!

  2. 为什么必须用 absolute?
    ① 让left: 50%/top: 50%生效:
    如果不设置position: absolute,left/top对 static(默认)定位的元素无效,translate(-50%, -50%)也只能基于元素自身原位置位移,无法实现 “基于父容器居中”。
    ② 适配大屏全屏布局:
    #container是 100vw*100vh(占满整个屏幕),scale-wrapper绝对定位后,能完全基于父容器的尺寸做居中 + 缩放,不会被文档流里的其他元素(比如头部、底部)挤压位置。
    ③ 为什么不用relative/fixed?
    relative:相对元素自身原位置定位,left:50%是 “相对于自身原位置向右移 50%”,无法基于父容器居中;
    fixed:相对视口定位,虽然也能实现居中,但如果组件嵌套在其他定位容器里,会导致位置错乱,absolute更适配当前组件的布局逻辑。

resize 是浏览器窗口的原生事件,当浏览器窗口的宽度 / 高度发生变化时(比如拖拽窗口边缘调整大小、最大化 / 最小化窗口、切换屏幕分辨率、移动端横竖屏切换等),这个事件会被触发

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐