扒一扒 Vue3 大屏适配插件 vfit 的源码:原来这么简单?

前几天用了 vfit 做大屏适配,感觉挺好用的。 作为一个有追求的前端(其实是闲得蛋疼),我忍不住扒了一下它的源码。 结果发现... 核心代码居然不到 50 行? 🤯

今天就带大家深入浅出地拆解一下这个库,看看它是如何优雅地解决大屏适配问题的。

🎯 核心原理:Scale 方案

大屏适配的核心流派无非就那几种:

  1. REM / VW:修改基准值,所有单位都要改,侵入性强。
  2. Scale :CSS transform: scale(),简单粗暴,不改变布局。

vfit 采用的是 Scale 方案。 它的思路非常清晰:

计算 当前屏幕宽高 / 设计稿宽高 = 缩放比例,然后应用到根容器上。

🔍 源码拆解

1. 监听屏幕变化 (ResizeObserver)

src/scale.ts 里,它没有使用传统的 window.onresize,而是用了更现代、性能更好的 ResizeObserver

typescript 复制代码
// src/scale.ts (简化版)
export function observeScale(target, designHeight, onScale) {
  const observer = new ResizeObserver((entries) => {
    for (const entry of entries) {
      const { width, height } = entry.contentRect
      // ... 计算 scale 逻辑
      onScale(scaleVal)
    }
  })
  observer.observe(target)
}

为什么用 ResizeObserver? 因为它能监听任意元素的大小变化,而不仅仅是 window。这意味着你可以把大屏嵌入到一个 div 里(比如后台管理系统的某个 dashboard 页签),它依然能正常缩放!

2. 三种缩放模式的算法

vfit 支持 width | height | auto 三种模式。 看看它是怎么算的:

typescript 复制代码
// src/scale.ts
if (scaleMode === 'height') {
  // 1. 只要高度撑满,宽度按比例缩放(适合定高宽屏)
  scaleVal = rectHeight / designHeight
} else if (scaleMode === 'width') {
  // 2. 只要宽度撑满,高度按比例缩放(适合定宽长页面)
  scaleVal = rectWidth / designWidth
} else {
  // 3. auto 模式 (默认):保持宽高比,全部显示 (Contain)
  const designRatio = designWidth / designHeight
  // 如果当前屏幕更宽(带鱼屏),就以高度为基准
  // 如果当前屏幕更窄(手机),就以宽度为基准
  if (rectWidth / rectHeight < designRatio) {
    scaleVal = rectWidth / designWidth
  } else {
    scaleVal = rectHeight / designHeight
  }
}

这段逻辑非常经典,保证了内容永远不会被裁剪,同时也保持了设计稿的比例。

3. 神奇的 FitContainer

大家用 scale 方案最头疼的是什么? 是定位! 😫 一旦缩放了,原来的 top: 100px 可能就不是视觉上的 100px 了,而且居中后的偏移量也很难算。

vfit 的 FitContainer.vue 组件用了一个很巧妙的思路解决这个问题:

typescript 复制代码
// src/components/FitContainer.vue

// 监听 scale 和 props 变化
watch([() => props.scale, fitScale], () => {
  const s = fitScale.value
  
  // 对于 left 和 top,乘以缩放比例 s
  // 这样就能让元素相对于原点进行位移
  if (key === 'left' || key === 'top') {
    position[key] = val * s + 'px'
  }
  
  // 对于 right 和 bottom,不乘!
  // 这样元素就会死死贴住容器边缘
  else {
    position[key] = val + 'px'
  }
})

这里有个细节设计得很赞:

  • top / left参与缩放。这意味着你给的坐标是相对于"设计稿左上角"的。
  • right / bottom不参与缩放。这意味着你给的坐标是相对于"屏幕边缘"的。

这解决了大屏开发的一个痛点:中间内容要还原设计稿,但边缘菜单要贴边。

💡 我们可以学到什么?

  1. API 设计要简单 :用户只关心 designWidthdesignHeight,不要把复杂的计算抛给用户。
  2. 善用现代 APIResizeObserverresize 事件更好用。
  3. 组件化思维 :通过 FitContainer 把"定位计算"封装起来,业务代码里就全是干净的 px 值了。

总结

vfit 的源码虽然简单,但确实切中了痛点。 有时候造轮子不一定要多高深的技术,能优雅地解决一个小问题,就是一个好轮子。

推荐大家去读读它的源码,就几个文件,半小时就能看完。 👉 GitHub: v-plugin/vfit

相关推荐
王霸天36 分钟前
拒绝 rem 计算!Vue3 大屏适配,我是这样做的 (vfit 使用体验)
前端
xinyu_Jina39 分钟前
ikTok Watermark Remover:客户端指纹、行为建模与自动化逆向工程
前端·人工智能·程序人生·信息可视化
盗德44 分钟前
最全音频处理WaveSurfer.js配置文档
前端·javascript
Heo1 小时前
关于Gulp,你学这些就够了
前端·javascript·面试
Irene19911 小时前
web前端开发岗位就业前景和未来变化分析(附:AI技术如何进一步影响前端工作)
前端
码途进化论1 小时前
基于 Node.js 和 SSH2 的 Docker 自动化部署实践
前端·自动化运维
溪饱鱼1 小时前
NextJs + Cloudflare Worker 是出海最佳实践
前端·后端
明川1 小时前
Android Gradle 学习 - Kts Gradle学习
前端·gradle