vue移动端rem适配--附带引入第三方库解决方案

一、先上解决方案:

移动端适配我采用淘宝的一套rem解决方案
源码: https://github.com/amfe/lib-flexible
1、安装 npm i -S amfe-flexible
2、引入meta标签

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

3、然后引入到项目 import ‘amfe-flexible’

4、到这里适配基本解决,但是我们再写的时候量出来的尺寸都需要除以75rem,这样很烦,这时引入插件postcss-px2rem-exclude解决px2rem的问题,为什么引入postcss-px2rem-exclude,而不是px2rem-loader,当你引入第三方插件库的时候你就知道痛点了,这里先不解释原因,下面会解释,先上结果:

  • 安装 cnpm i postcss-px2rem-exclude –save
  • 然后在.postcssrc.js配置
module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {},
    'postcss-px2rem-exclude': {
      remUnit: 75,
      exclude: /node_modules|folder_name/i
    }
  }
}

6、这时重启一下。到这里我们已经实现了移动端适配,并且是基于750的设计稿量出多少写多少px,然后我们引入第三方库也是没问题的,这里我引入echarts和mintUI已经实验过了。
demo源码请见: https://github.com/qiuzhaofeng/flexible-demo

二、下面我们来看看这些插件的原理以及为什么引入这些插件

首先咱们先了解一下viewport

移动设备上的viewport就是设备的屏幕上能用来显示我们的网页的那一块区域,在具体一点,就是浏览器上(也可能是一个app中的webview)用来显示网页的那部分区域,

  • width:控制 viewport 的大小,可以指定的一个值,如 600,或者特殊的值,如 device-width 为设备的宽度(单位为缩放为 100% 时的 CSS 的像素)。
  • height:和 width 相对应,指定高度。
  • initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。
  • maximum-scale:允许用户缩放到的最大比例。
  • minimum-scale:允许用户缩放到的最小比例。
  • user-scalable:用户是否可以手动缩放。

我们会发现width这个属性,让viewport的宽等于设备的宽,我们都知道移动端的我们设置的css的1px并不等于设备的1px,因为移动端window对象有一个devicePixelRatio属性,也就是设备像素比dpr,他是设备的物理像素与逻辑像素的比例,我们看到的设备的宽度就是设备的逻辑像素,以我们的iphone6和6plus他们的dpr为2、3,那么他们的物理像素对应的就是设备宽*dpr,所以我们设置的css的1px为逻辑像素,是物理像素的2到3倍,(当然这里默认不缩放,横向或竖向比例),这时我就有一个疑问了,那么这么搞不就相当于用我们css设置的1px覆盖dpr大的上面更多的点,解决了适配问题,但是并没有解决更精确更清晰的问题,应该让我们设置的1px等于设备的物理像素不就行了,不错,淘宝rem适配方案在之前有解决这个问题,我们先来看一下:
源码:https://github.com/amfe/lib-flexible/blob/master/src/flexible.js

源码动态生成viewport,并且没有设置width=divice-width,为的是让我们设置的1px等于设备的物理像素,然后结合动态计算的scale来实现充满区域。我们来导入看一下由于动态生成meta,我们把meta标签删掉,
vue移动端rem适配--附带引入第三方库解决方案_第1张图片
vue移动端rem适配--附带引入第三方库解决方案_第2张图片
完美解决,让我们的css1px等于了设备的物理像素,但是为什么作者说lib-flexible这个东西已放弃呢,有图有真相
vue移动端rem适配--附带引入第三方库解决方案_第3张图片
他说存在一定的问题,也没说什么问题,
那我们继续引入第三方插件库试试,
vue移动端rem适配--附带引入第三方库解决方案_第4张图片
大家会清楚的看到这第三方插件库怎么这么小啊,为什么呢?
我们看下mintUI的源码
vue移动端rem适配--附带引入第三方库解决方案_第5张图片
再看下他里面的单位
vue移动端rem适配--附带引入第三方库解决方案_第6张图片
大家可以看到咱们在这欢乐的动态生成viewport,但是第三方库并没有,人家写死的,除了一些flex或百分比布局,其他都是按逻辑像素走的px,放到我们这个按物理像素走的区域上能不小吗?大家不信可以试一下dpr为1的设备,算了,我还是截个图吧
vue移动端rem适配--附带引入第三方库解决方案_第7张图片
进一步验证了我们的结果,
作者为什么放弃这个lib-flexible动态生成viewport转而在amfe-flexible中写死,我猜其中一个原因应该是干不过许许多多的第三方库。(仅为本人猜测)。
这里有人可能会说把第三方库的px也转成rem,大家想一下,第三方库是按照逻辑像素走的,而这里我们是按物理像素走的,首先大的宽度都不对,更不用说里面的像素了。
到这里我们确定这个lib-flexible再引入第三方库的时候是不可取得,当然我们的项目中一般都会出现第三方库,所以这里我们来回到我们的amfe-flexible。
然后我们这里来说一下为什么选择postcss-px2rem-exclude而不是px2rem-loader
我们首先引入配置一下px2rem-loader,在utils.js

const px2remLoader = {
    loader: 'px2rem-loader',
    options: {
      remUnit: 75
    }
  }

  // generate loader string to be used with extract text plugin
  function generateLoaders (loader, loaderOptions) {
    const loaders = options.usePostCSS ? [cssLoader, px2remLoader, postcssLoader] : [cssLoader, px2remLoader]

    if (loader) {
      loaders.push({
        loader: loader + '-loader',
        options: Object.assign({}, loaderOptions, {
          sourceMap: options.sourceMap
        })
      })
    }

这个插件是将全局的px都转化成rem,这里我们的项目的viewport是写死的,也就是都是按照逻辑像素走的,按照正常思维是没错的,大家可以看下截图
vue移动端rem适配--附带引入第三方库解决方案_第8张图片
看着没问题啊,但是你看到的这些是用flex布局或者百分比布局的,我们来看下具体到px的,
vue移动端rem适配--附带引入第三方库解决方案_第9张图片
这个确定、取消的宽度比之前小了一倍,为什么呢?
在不转rem之前,插件里面写死的是40px;而我们转过之后40/75rem,
在iphone6下1rem=37.5px,算出来的就是19.9999px,也就是小了一倍,
出现这种问题的原因当然是我们的rem是按照750设计稿转的,然而mintUI里面并没有和我们的一致,也许人家的适配已经转过了结果就是40px;而我们这里又转一遍,所以就出现了 postcss-px2rem-exclude这个插件,他的目的是不转第三方库,完美解决我们的问题。
到这里我们的移动端适配就介绍完了,这个适配就是按照设备逻辑像素也叫独立像素的适配。

你可能感兴趣的:(移动端)