Vue和React工程移动端适配方案

740 阅读3分钟

在早期的移动端适配方案中,rem 是一种比较常见的适配方案,这一相对于根元素大小的单位,只用动态改变根元素字体大小,就能改变页面中的布局,能比较方便的实现适配各个尺寸的设备;随着移动端对视口(viewport)单位的支持越来越成熟、广泛,而且相对于rem单位来说更为简单,所以在目前移动端的开发中基本都会使用 viewport 去布局,同样也能很方便的实现适配所有尺寸的设备。下面简单说下在实际开发中Vue工程和React工程的配置方案。

1. Vue工程配置

vue工程一般用的是vantUI组件库,是一个移动端比较好用的UI组件库。

Vant 是有赞前端团队开源的移动端组件库,于 2017 年开源,已持续维护 4 年时间。Vant 对内承载了有赞所有核心业务,对外服务十多万开发者,是业界主流的移动端组件库之一。

1. viewport 布局适配(推荐)

vant提供了viewport布局移动端适配方案,其原理很简单,就是借助 postcss-px-to-viewport 插件将 px 单位转化为 vw/vh 单位,所以也同样适用于其他默认单位是 px 的UI库,这个配置比较简单:

// postcss.config.js

module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375, // /750
    },
  },
};

2. rem 布局配置

rem 适配是在 viewport 流行之前移动端比较常见的自适应布局方式,因为 rem 单位是一个相对单位,相对于根元素字体大小的单位,所以 rem 单位适配需要借助两个工具:

  • postcss-pxtorem 是一款 PostCSS 插件,用于将 px 单位转化为 rem 单位
  • amfe-flexible 用于设置 rem 基准值,用来动态设置根元素的字体大小
  1. 安装:
npm i -S amfe-flexible postcss postcss-pxtorem
  1. man.js 文件中引入 amfe-flexible
// main.js
...
import "amfe-flexible";
...
  1. 配置 postcss.config.js
// postcss.config.js

module.exports = ({ file }) => {
  let isVant = file && file.dirname && file.dirname.indexOf("vant") > -1;
  let rootValue = isVant ? 37.5 : 75; // 依据设计稿,自行调整
  return {
    plugins: {
      'autoprefixer': {
        overrideBrowserslist: [
          "Android 4.1",
          "iOS 7.1",
          "Chrome > 31",
          "ff > 31",
          "ie >= 8"
        ]
      },
      'postcss-pxtorem': {
        rootValue: rootValue,
        propList: ["*", "!border"]
      }
    }
  }
}

更推荐使用 viewport 的适配方案,毕竟amfe-flexible插件的作者都给出了说明:

由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方。

2. React工程配置

react工程使用的是 viewprot 适配方案,也是借助 postcss-px-to-viewport 插件实现 px 单位的转换,以下是 umiJS 中的配置方案:

// config.ts

...
extraPostCSSPlugins: [
  // 移动端适配
  require('postcss-px-to-viewport')({
    viewportWidth: 375, // 视窗的宽度,对应的是我们设计稿的宽度,一般是375/750
    unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
    viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
    selectorBlackList: [], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
    minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
    mediaQuery: false, // 允许在媒体查询中转换`px`
  }),
],