Vue2移动端使用felxbilejs自适应

背景

Vue 2 项目要做移动端,设计稿通常是 750px 宽。每次写样式时都要算"设计稿 32px 等于实际多少 rem",效率太低。用 lib-flexible + postcss-px2rem 这套组合,代码里直接写 px,运行时自动适配各种屏幕。

注:lib-flexible 在 Vue 3 项目里改用 amfe-flexible + postcss-pxtorem,本文是 Vue 2 + Webpack 老项目方案。

Vue2移动端使用felxbilejs自适应

装两个包

npm install lib-flexible postcss-px2rem --save

两个包的作用:

  • lib-flexible:运行时,根据 viewport 宽度动态设置 htmlfont-size。屏幕 750px 时根字号 75px,屏幕 375px 时 37.5px,以此类推。
  • postcss-px2rem:构建时,扫描所有 CSS 把 px 除以 remUnit 转成 rem

项目 package.json 参考

{
    "name": "XiaoDong",
    "version": "0.1.0",
    "private": true,
    "scripts": {
        "serve": "vue-cli-service serve",
        "build": "vue-cli-service build"
    },
    "dependencies": {
        "axios": "^1.3.2",
        "core-js": "^3.25.3",
        "less": "^3.0.4",
        "less-loader": "^5.0.0",
        "lib-flexible": "^0.3.2",
        "pinia": "^2.0.32",
        "pinia-plugin-persist": "^1.0.0",
        "postcss-px2rem": "^0.3.0",
        "qrcode": "^1.5.1",
        "vant": "^2.12.53",
        "vue": "^2.7.0",
        "vue-canvas-poster": "^1.2.1",
        "vue-cookies": "^1.8.2",
        "vue-moment": "^4.1.0",
        "vue-router": "^3.2.0",
        "vuex": "^3.4.0"
    },
    "devDependencies": {
        "@vue/cli-plugin-babel": "~4.5.19",
        "@vue/cli-plugin-router": "~4.5.19",
        "@vue/cli-plugin-vuex": "~4.5.19",
        "@vue/cli-service": "~4.5.19",
        "babel-plugin-import": "^1.13.6",
        "prettier": "2.8.4",
        "vue-template-compiler": "^2.7.0"
    }
}

main.js 引入 flexible

项目入口顶上加一行:

// src/main.js
import 'lib-flexible'
import Vue from 'vue'
import App from './App.vue'

new Vue({
    render: h => h(App)
}).$mount('#app')

这一行 import 后,lib-flexible 自动接管 htmlfont-sizemeta[name=viewport]。打开浏览器看 <html> 元素,会发现它的 style="font-size: 37.5px;" 之类的属性(根据屏幕动态调整)。

vue.config.js 配置 px2rem

// vue.config.js
module.exports = {
    publicPath: '/vote/',
    css: {
        loaderOptions: {
            css: {},
            postcss: {
                plugins: [
                    require('postcss-px2rem')({
                        remUnit: 37.5
                    })
                ]
            }
        }
    }
}

remUnit 怎么定:

  • Vant 2.x 之类的 UI 库 → remUnit: 37.5(Vant 内部就是按 37.5 设计的,要对齐)
  • 纯手写 / 设计稿 750px → remUnit: 75
  • 设计稿 1080px → remUnit: 108

规则:remUnit = 设计稿宽度 ÷ 10。Vant 用 37.5 是因为它内部以 375px 为基准(iPhone 6/7/8 的 viewport)。

使用示例

配置完成后,直接写 px 就行,不用手动算 rem:

<template>
    <div class="card">
        <h2 class="title">商品标题</h2>
        <p class="price">¥99.00</p>
    </div>
</template>

<style lang="less" scoped>
.card {
    padding: 20px;        /* 自动转 rem,屏幕宽度等比缩放 */
    background: #fff;
    border-radius: 8px;
}
.title {
    font-size: 32px;      /* 自动转 rem */
    color: #333;
}
.price {
    font-size: 28px;
    color: #ee0a24;
    margin-top: 12px;
}
</style>

构建出来 32pxremUnit: 37.5 下,会变成 32 / 37.5 ≈ 0.853rem。再乘以运行时 html font-size(动态值),就是最终像素值。

不想转的怎么办(白名单)

有些场景不想转,比如 border: 1px solid #eee 这种 hairline 边框,转 rem 后在 hidpi 屏会糊。

解决:在 px 后面加 /*no*/ 注释,px2rem 看到就不转:

.line {
    border-top: 1px solid #eee;   /* 会被转成 0.026rem,糊 */
    border-top: 1px /*no*/ solid #eee;  /* 不转,保留 1px */
}

更全局的做法用 postcss-px2rem-exclude 配置黑名单文件夹,但项目级里 /*no*/ 注释最灵活。

常见坑

1. flexible 没生效,字体不缩放

  • 检查 main.js 里 import 'lib-flexible' 是否在最顶部
  • F12 看 html 元素,style 里有没有 font-size。没有就是 lib-flexible 没跑起来

2. iPhone 横屏字超大

横屏 viewport 变成 667px,根字号变 66.7px,所有元素都翻倍。解决:CSS 里用媒体查询固定大屏字号:

@media screen and (orientation: landscape) and (max-width: 1024px) {
    html { font-size: 37.5px !important; }
}

3. 1px 边框在 iPhone 上变粗

这是 hidpi 屏的问题,跟 flexible 无关。解决用 transform: scale(0.5) 伪元素技巧,或者 Vant 自带的 hairline 组件。

Vue 3 / Vite 项目的替代

新项目不推荐 lib-flexible + postcss-px2rem 这套(俩包都不再维护)。改用:

npm install amfe-flexible postcss-pxtorem --save

Vite 配置:

// vite.config.ts
import postcssPxToRem from 'postcss-pxtorem'

export default defineConfig({
    css: {
        postcss: {
            plugins: [
                postcssPxToRem({
                    rootValue: 37.5,
                    propList: ['*'],
                    minPixelValue: 2
                })
            ]
        }
    }
})

API 几乎一样,但用的是社区还在维护的版本。

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

Nuxt3.js移动端Pc端自适应解决方案:使用flexible.js和postcss-pxtorem实现傻瓜式Px转Rem

2023-5-17 20:23:22

技术教程

解决Nuxt3项目创建项目失败链接失败等问题

2023-6-20 11:34:59

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