Vue移动端适配vw和 postcss-px-to-viewport使用

vw 适配 vs rem 适配

Vue 移动端做适配,传统方案是 lib-flexible + postcss-px2rem(动态调 html 根字号 + 转 rem)。但社区慢慢转向更纯粹的方案:用 vw 单位,完全不依赖运行时 JS。

vw(viewport width)是 CSS 单位,1vw = 视口宽度的 1%。比如视口 375px 宽,1vw = 3.75px。直接用 vw 替代 px,浏览器原生适配,不需要任何 JS 介入。

对比:

方案 原理 优劣
lib-flexible + rem JS 调 html font-size,CSS 用 rem 依赖 JS,可手动控制根字号
vw + postcss 自动转 CSS 原生单位,无 JS 大屏字体太大,需要额外限制

Vue移动端适配vw和 postcss-px-to-viewport使用

安装 postcss-px-to-viewport

npm:

npm i postcss-px-to-viewport -D

pnpm:

pnpm i -D postcss-px-to-viewport

Vue 3 项目推荐用维护更活跃的 postcss-px-to-viewport-8-plugin(支持 PostCSS 8):

pnpm i -D postcss-px-to-viewport-8-plugin

项目配置 postcss.config.js

项目根目录新建 postcss.config.js:

module.exports = {
    plugins: {
        // 处理大屏限制,vw 在 PC 上会让字体非常大,这个插件加 max-width 容器
        'postcss-mobile-forever': {
            appSelector: '#app',
            viewportWidth: 375,
            maxDisplayWidth: 640,
            enableMediaQuery: true,
            disableMobile: true
        },
        // 主力:px 转 vw
        'postcss-px-to-viewport-8-plugin': {
            unitToConvert: 'px',
            viewportWidth: file => {
                let num = 750
                if (file.indexOf('van') > 0) {
                    num = 375    // Vant 组件库内部按 375 设计
                }
                return num
            },
            unitPrecision: 5,
            propList: ['*'],
            viewportUnit: 'vw',
            fontViewportUnit: 'vw',
            selectorBlackList: [],
            minPixelValue: 1,
            mediaQuery: true,
            replace: true,
            exclude: [/node_modules/vant/i],
            include: [],
            landscape: false,
            landscapeUnit: 'vw',
            landscapeWidth: 1628
        }
    }
}

关键配置项详解

  • viewportWidth —— 设计稿宽度。不同来源的代码可以分别对待 —— Vant 内部按 375 设计,自家代码按 750 设计,这种就用函数动态返回。
  • unitPrecision: 5 —— vw 保留 5 位小数(1.46667vw),足够精确。
  • propList: ['*'] —— 所有 CSS 属性都转。可以排除某些属性(比如不转 border-width):['*', '!border']
  • viewportUnit / fontViewportUnit: 'vw' —— 字体用 vw 还是 vmin,移动端竖屏用 vw 即可。
  • selectorBlackList: [] —— 选择器黑名单。比如 ['.pc-'] 表示 class 含 pc- 的不转。
  • minPixelValue: 1 —— 小于 1px 不转(避免 0.5px 这种 hairline 边框被转)。
  • exclude —— 文件黑名单。常见做法:排除 node_modules/vant 因为 Vant 已经处理过自己的尺寸。

postcss-mobile-forever 解决大屏问题

纯 vw 适配有个尴尬:用户用 1920px 显示器全屏访问移动端页面,字体会变成超大,布局崩。

postcss-mobile-forever 解决这个问题:超过某个宽度时,把 #app 容器限制成固定 max-width,两边留白,移动端体验保持不变。

npm install --save-dev postcss postcss-mobile-forever

配置见上面的 postcss.config.js,关键参数:

  • appSelector: '#app' —— 你的根挂载点
  • viewportWidth: 375 —— 设计稿基准
  • maxDisplayWidth: 640 —— 超过这个宽度就限制 max-width
  • enableMediaQuery: true —— 加 media query
  • disableMobile: true —— 移动设备本身不动,正常 vw 适配

启用后,PC 浏览器全屏看 H5 项目时,内容会被限制在中间 640px 区域,两边背景留白,既不变形也不丑。

实际使用

配置完后,代码里照常写 px,构建时自动转 vw:

<style lang="less" scoped>
.card {
    padding: 20px;            /* → 2.667vw(750 设计稿) */
    background: #fff;
    border-radius: 8px;
}
.title {
    font-size: 32px;          /* → 4.267vw */
    color: #333;
    line-height: 1.5;
}
.price {
    font-size: 28px;
    color: #ee0a24;
    margin-top: 12px;
}
</style>

关键技巧:跨 UI 库的尺寸基准切换

上面配置里这段精华:

viewportWidth: file => {
    let num = 750
    if (file.indexOf('van') > 0) {
        num = 375
    }
    return num
}

原因:Vant 是按 375 设计稿做的内部样式。如果你的设计稿是 750,Vant 组件直接套进去会"小一半"。这段函数让 postcss 处理 Vant 文件时按 375 转换,处理你自己代码时按 750,各自正常显示。

同样的技巧适用于:NutUI、Varlet、其他移动 UI 库,看它们的设计稿基准是什么。

对比 rem 方案

选择建议:

  • 新项目 → vw + postcss-px-to-viewport。配套 postcss-mobile-forever 解决大屏问题。CSS 原生,无 JS 依赖,SSR 友好。
  • 老项目用 rem,改不动 → 继续用 lib-flexible。改造成本不值得。
  • 用 Tailwind / UnoCSS → 都不用。直接用框架自带的响应式类名。

相关延伸阅读:掘金 - vw 适配方案对比

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

解决Vue项目每次更新浏览器缓存问题

2023-10-13 16:52:26

技术教程

深入解析4层代理和7层代理的区别:优化网络性能的关键选择

2023-10-23 10:48:00

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索