目录
1. Media Query + Flex/Grid(CSS 响应式基础方案)
3. useMediaQuery:用 JavaScript 动态判断设备
4. vite-plugin-style-import:按需加载组件样式
5. lib-flexible + postcss-pxtorem(H5 经典组合)
7. VueUse 的 useWindowSize 实时监听
移动端和 PC 端适配,一直是前端开发中绕不过去的话题。是写两套代码,还是一套代码搞定双端?本篇文章将为你系统梳理 8 种主流适配方式,并结合实践案例进行优缺点对比,助你轻松实现“一套代码多端适配”。
💡 为什么要做双端适配?
在实际开发中,很多项目需要同时支持:
-
移动端:H5 页面、小程序 WebView、微信内嵌页等
-
PC 端:后台管理系统、大屏展示页、Web 应用等
我们追求的目标是:同一套代码,自动适配不同设备,提升开发效率,降低维护成本。
🧰 一套代码多端适配的 8 大方案
1. Media Query + Flex/Grid(CSS 响应式基础方案)
核心思路:
使用 CSS 的 @media
媒体查询结合 Flex/Grid 布局,根据屏幕宽度切换样式。
/* 默认 PC 样式 */
.container {
display: flex;
padding: 40px;
}
/* 移动端样式 */
@media screen and (max-width: 768px) {
.container {
flex-direction: column;
padding: 16px;
}
}
✅ 适合:结构简单、样式分离明确的页面
❌ 缺点:
-
样式分支多,维护困难
-
动态渲染组件能力较弱
2. rem / vw+vh 响应式布局(移动端主打方案)
rem 方案:
通过设置 html
的 font-size
来实现全局缩放,一般配合 postcss-pxtorem
插件使用。
// main.ts
document.documentElement.style.fontSize = window.innerWidth / 10 + 'px';
vw/vh 方案:
CSS 单位直接使用 vw
(视口宽度百分比)、vh
(视口高度百分比)
.container {
width: 80vw;
height: 60vh;
}
✅ 优点:
-
自动缩放,适配流畅
-
配合 UI 组件库易用(如 Vant)
❌ 缺点:
-
在 PC 上可能因字体过大/小产生不适
-
rem 对字体控制精准度差,vw 在极宽屏设备下表现异常
3. useMediaQuery:用 JavaScript 动态判断设备
原理:
使用 window.matchMedia
或封装好的 Composition API 判断屏幕类型。
const isMobile = computed(() => window.matchMedia('(max-width: 768px)').matches);
✅ 优点:
-
可以动态切换组件或布局,灵活控制
-
减少无用 DOM,提高性能
❌ 缺点:
-
增加逻辑复杂度
-
样式和逻辑耦合可能增加维护成本
4. vite-plugin-style-import:按需加载组件样式
当你使用多端 UI 组件库(如 PC 端 Ant Design Vue,移动端 Vant)时,可以用插件进行按需引入。
// vite.config.ts
styleImport({
libs: [
{
libraryName: 'vant',
esModule: true,
resolveStyle: name => `vant/es/${name}/style`
}
]
})
✅ 优点:
-
减小打包体积
-
提高加载速度
❌ 缺点:
-
仅解决组件库样式加载问题
-
不处理布局适配
5. lib-flexible + postcss-pxtorem(H5 经典组合)
这是一套非常成熟的移动端适配方案,主要通过 lib-flexible
设置 html
的 font-size,配合 postcss-pxtorem
自动将 px 转为 rem。
// 安装依赖
npm install amfe-flexible postcss-pxtorem
// main.ts
import 'amfe-flexible'
✅ 优点:
-
自动适配,效果稳定
-
适用于所有主流移动端项目
❌ 缺点:
-
PC 端兼容性差
-
与部分 UI 库(如 Element Plus)可能冲突
6. Tailwind CSS 响应式设计(推荐)
Tailwind 提供了非常直观的响应式语法,如 sm:
, md:
, lg:
,让你不用再写 @media
。
<div class="text-base sm:text-lg md:text-xl lg:text-2xl">
响应式文字大小
</div>
✅ 优点:
-
开发效率高
-
响应式写法结构清晰
❌ 缺点:
-
需要学习 Tailwind 语法
-
样式“原子化”风格不一定适合所有团队
7. VueUse 的 useWindowSize 实时监听
VueUse 提供了一套响应式 Hooks,其中 useWindowSize
可用于实时获取窗口尺寸:
import { useWindowSize } from '@vueuse/core';
const { width } = useWindowSize();
const isMobile = computed(() => width.value < 768);
✅ 优点:
-
更加响应实时变化
-
和 Composition API 配合天然
❌ 缺点:
-
JS 逻辑较多,依赖额外库
-
不可完全取代 CSS 的媒体查询
8. 双端组件拆分(终极方案)
当移动端和 PC 端差异非常大时,不如直接分别写两个组件,然后条件加载。
<template>
<MobileLayout v-if="isMobile" />
<PCLayout v-else />
</template>
✅ 优点:
-
各自优化极致,代码清晰
-
适合复杂项目,如管理后台 + 小程序 Web 页面共用代码
❌ 缺点:
-
代码量翻倍,维护成本高
-
组件状态管理需额外考虑
🧭 多端适配策略对比表
方案 | 适用场景 | 维护成本 | 灵活性 | 推荐指数 |
---|---|---|---|---|
Media Query | 简单响应式页面 | 低 | 中 | ⭐⭐⭐ |
rem / vw | 移动端优先项目 | 中 | 中 | ⭐⭐⭐⭐ |
useMediaQuery | 组件级适配 | 中 | 高 | ⭐⭐⭐⭐ |
style-import | 不同 UI 库加载 | 低 | 低 | ⭐⭐⭐ |
lib-flexible | 移动端 H5 | 中 | 中 | ⭐⭐⭐⭐ |
Tailwind CSS | 快速开发 | 低 | 高 | ⭐⭐⭐⭐ |
useWindowSize | 实时响应 | 中 | 高 | ⭐⭐⭐⭐ |
双端组件 | 差异极大项目 | 高 | 极高 | ⭐⭐⭐⭐⭐ |
🎯 实战推荐组合方案
场景 | 推荐方案 |
---|---|
移动端为主 | lib-flexible + rem + postcss-pxtorem |
PC 与移动端共存 | Tailwind CSS + useWindowSize |
双端差异巨大 | 双端组件 + useMediaQuery |
📁 示例结构建议(项目目录)
src/
├── components/
│ ├── pc/
│ └── mobile/
├── layouts/
│ ├── PCLayout.vue
│ └── MobileLayout.vue
├── utils/
│ └── device.ts
└── App.vue
✅ 总结
“一套代码多端适配”并没有银弹,适配策略的选择必须结合项目场景:
-
简单项目:媒体查询或 rem 足够
-
组件复用多:VueUse + Tailwind 更灵活
-
大型复杂系统:双端组件 + 动态渲染是王道
希望本篇文章能帮你在下次启动项目时,不再为“要不要写两套代码”而头疼。如果觉得有帮助,欢迎点赞、收藏、关注我,一起深入前端实践!