使用amfe-flexible以及px2rem-loader解决VUE移动端适配

1.安装

cnpm  install -S amfe-flexible

cnpm install postcss-pxtorem@5.1.1 -D

2.在main.js

import 'amfe-flexible'

3.在vue.config.js 添加

module.exports = {

  lintOnSave: false,

    css: {
      loaderOptions: {
        postcss: {
          plugins: [
            require('postcss-pxtorem')({ // 把px单位换算成rem单位
              rootValue: 37.5, // vant官方使用的是37.5
              selectorBlackList: ['vant', 'mu'], // 忽略转换正则匹配项
              propList: ['*']
            })
          ]
        }
      }
    }
}

3.1或者在package.json里添加

 "postcss": {
    "plugins": {
      "autoprefixer": {},
      "postcss-pxtorem": {
        "rootValue": 37.5,
        "propList": [
          "*"
        ]
      }
    }
  }

4.重启

5.完成

image.png

前言

前段时间我的移动端适配解决方案[2]一文在评论区引发了激烈的讨论。其中讨论最多的就是,移动端rem的适配已经淘汰了,目前大家使用的都是viewport。lib-flexible作者也在github明确的表示lib-flexible这个解决方案可以放弃使用了。

由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。
看到大家的讨论,我受益匪浅。在这里也向那些阅读过我之前那篇移动端适配解决方案[3]文章的同行们说一声对不起。rem适配方案确实是已经淘汰了。

本文带大家一起来看看评论区所说的viewport适配解决方案。

什么是viewport

viewport翻译成中文的意思大致是视图、视窗。在移动端设备中,整块显示屏就相当于视图、视窗。但这种说法也并不完全正确。因为在移动端设备中,浏览器视图并不是整个屏幕。因此viewport又被分为了3种 layout viewport、visual viewport、ideal viewport

为了能够适配到pc端开发页面中,大部分浏览器把viewport的宽度设为了980px 这个浏览器默认设置的视图被称为 layout viewport。我们可以使用document.documentElement.clientWidth 来获取。

由于 layout viewport的宽度是远大于浏览器宽度的,因此我们需要一个新的viewport来代表浏览器的可视区域宽度,这个视图则被成为visual viewport我们可以使用window.innerWidth来获取。

现在我们已经有两个viewport了,layout viewport 和 visual viewport。但浏览器觉得还不够,因为现在越来越多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的ideal viewport。

ideal viewport 并没有一个固定的尺寸,不同的设备拥有有不同的 ideal viewport。比如iphone5的 ideal viewport是 320px 而 iphone6s的 ideal viewport却是 375px

viewport的单位vw、vh

vw、vh将viewport分成了一百份。vw即 viewport width vh即viewport height

1vw等于视图单位的1%的宽度
1vh等于视图单位的1%的高度
如果设计稿的视图为375px 那么1vw 等于 3.75px

在配置开始之前 我们依然需要一个vue-cli项目 在项目的index.html 我们需要在head标签中添加如下代码

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

viewport适配解决方案

之前的文章,我们用到了阿里巴巴手淘团队出品的amfe-flexible这个库。目的是为了获取到不同移动端设备下的像素比。对于rem的适配该库是至关重要的。本篇文章使用viewport适配则不再需要。

要使用viewport适配 我们必须安装postcss-px-to-viewport这个包。这包名是不是有一种似曾相识的感觉。

没错,上篇文章中我们使用过postcss-pxtorem。这两个包不仅名字相似,功能也有相似的地方。postcss-pxtorem是将 px单位转换为rem单位。postcss-px-to-viewport则是将px单位转换为vw、vh

//引入 postcss-px-to-viewport
 npm install postcss-px-to-viewport --save-dev

安装完成后 我们需要进行postcss插件相关的配置 在根目录新建一个名为postcss.config.js的文件,如果项目中已包含该文件则无需新建。在文件中写入如下代码:

//postcss.config.js

module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
     unitToConvert: "px", // 要转化的单位       
     viewportWidth: 375, // UI设计稿的宽度       
     unitPrecision: 6, // 转换后的精度,即小数点位数       
     propList: ["*"], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换     
     viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw       
     fontViewportUnit: "vw", // 指定字体需要转换成的视窗单位,默认vw      selectorBlackList: ["wrap"], // 指定不转换为视窗单位的类名,       
     minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换       
     mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false      
     replace: true, // 是否转换后直接更换属性值       
     exclude: [/node_modules/], // 设置忽略文件,用正则做目录名匹配       
    }
  }
}

在配置上这两个包也有相似的功能。大家可以去参考一下postcss-px-to-viewport作者的github[4]

值得注意的是:postcss-px-to-viewport 同样存在第三方组件库兼容性的问题。比如在设计稿为750px时使用vant组件库会将vant组件的样式缩小。

解决第三方组件库兼容问题

vant组件库的设计稿是按照375px来开发的。因此在viewportWidth为750px时会出现转换问题。

// postcss.config.js
const path = require('path');

module.exports = ({ webpack }) => {
  const viewWidth = webpack.resourcePath.includes(path.join('node_modules', 'vant')) ? 375 : 750;
  return {
    plugins: {
      autoprefixer: {},
      "postcss-px-to-viewport": {
        unitToConvert: "px",
        viewportWidth: viewWidth,
        unitPrecision: 6,
        propList: ["*"],
        viewportUnit: "vw",
        fontViewportUnit: "vw",
        selectorBlackList: [],
        minPixelValue: 1,
        mediaQuery: true,
        exclude: [],
        landscape: false
      }
    }
  }
}

如果读取的node_modules中的文件是vant,那么就将设计稿变为375px。如果读取的文件不是vant的文件,那么就将设计稿变为750px。这样就可以避免vant组件在750px下出现样式缩小的问题了。

同理 这对于其他的移动端UI组件库同样有效果。我们只需要改动这行代码即可

const viewWidth = webpack.resourcePath.includes(path.join('node_modules', 'vant')) ? 375 : 750; 

至此,我们的viewport的适配就做好了,只需要按照设计稿的比例进行开发就可以了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,376评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,126评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,966评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,432评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,519评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,792评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,933评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,701评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,143评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,488评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,626评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,292评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,896评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,494评论 2 348

推荐阅读更多精彩内容