使用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'], // 忽略轉(zhuǎn)換正則匹配項
              propList: ['*']
            })
          ]
        }
      }
    }
}

3.1或者在package.json里添加

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

4.重啟

5.完成

image.png

前言

前段時間我的移動端適配解決方案[2]一文在評論區(qū)引發(fā)了激烈的討論。其中討論最多的就是,移動端rem的適配已經(jīng)淘汰了,目前大家使用的都是viewport。lib-flexible作者也在github明確的表示lib-flexible這個解決方案可以放棄使用了。

由于viewport單位得到眾多瀏覽器的兼容,lib-flexible這個過渡方案已經(jīng)可以放棄使用,不管是現(xiàn)在的版本還是以前的版本,都存有一定的問題。建議大家開始使用viewport來替代此方案。
看到大家的討論,我受益匪淺。在這里也向那些閱讀過我之前那篇移動端適配解決方案[3]文章的同行們說一聲對不起。rem適配方案確實是已經(jīng)淘汰了。

本文帶大家一起來看看評論區(qū)所說的viewport適配解決方案。

什么是viewport

viewport翻譯成中文的意思大致是視圖、視窗。在移動端設備中,整塊顯示屏就相當于視圖、視窗。但這種說法也并不完全正確。因為在移動端設備中,瀏覽器視圖并不是整個屏幕。因此viewport又被分為了3種 layout viewport、visual viewport、ideal viewport

為了能夠適配到pc端開發(fā)頁面中,大部分瀏覽器把viewport的寬度設為了980px 這個瀏覽器默認設置的視圖被稱為 layout viewport。我們可以使用document.documentElement.clientWidth 來獲取。

由于 layout viewport的寬度是遠大于瀏覽器寬度的,因此我們需要一個新的viewport來代表瀏覽器的可視區(qū)域?qū)挾龋@個視圖則被成為visual viewport我們可以使用window.innerWidth來獲取。

現(xiàn)在我們已經(jīng)有兩個viewport了,layout viewport 和 visual viewport。但瀏覽器覺得還不夠,因為現(xiàn)在越來越多的網(wǎng)站都會為移動設備進行單獨的設計,所以必須還要有一個能完美適配移動設備的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的適配該庫是至關(guān)重要的。本篇文章使用viewport適配則不再需要。

要使用viewport適配 我們必須安裝postcss-px-to-viewport這個包。這包名是不是有一種似曾相識的感覺。

沒錯,上篇文章中我們使用過postcss-pxtorem。這兩個包不僅名字相似,功能也有相似的地方。postcss-pxtorem是將 px單位轉(zhuǎn)換為rem單位。postcss-px-to-viewport則是將px單位轉(zhuǎn)換為vw、vh

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

安裝完成后 我們需要進行postcss插件相關(guān)的配置 在根目錄新建一個名為postcss.config.js的文件,如果項目中已包含該文件則無需新建。在文件中寫入如下代碼:

//postcss.config.js

module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
     unitToConvert: "px", // 要轉(zhuǎn)化的單位       
     viewportWidth: 375, // UI設計稿的寬度       
     unitPrecision: 6, // 轉(zhuǎn)換后的精度,即小數(shù)點位數(shù)       
     propList: ["*"], // 指定轉(zhuǎn)換的css屬性的單位,*代表全部css屬性的單位都進行轉(zhuǎn)換     
     viewportUnit: "vw", // 指定需要轉(zhuǎn)換成的視窗單位,默認vw       
     fontViewportUnit: "vw", // 指定字體需要轉(zhuǎn)換成的視窗單位,默認vw      selectorBlackList: ["wrap"], // 指定不轉(zhuǎn)換為視窗單位的類名,       
     minPixelValue: 1, // 默認值1,小于或等于1px則不進行轉(zhuǎn)換       
     mediaQuery: true, // 是否在媒體查詢的css代碼中也進行轉(zhuǎn)換,默認false      
     replace: true, // 是否轉(zhuǎn)換后直接更換屬性值       
     exclude: [/node_modules/], // 設置忽略文件,用正則做目錄名匹配       
    }
  }
}

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

值得注意的是:postcss-px-to-viewport 同樣存在第三方組件庫兼容性的問題。比如在設計稿為750px時使用vant組件庫會將vant組件的樣式縮小。

解決第三方組件庫兼容問題

vant組件庫的設計稿是按照375px來開發(fā)的。因此在viewportWidth為750px時會出現(xiàn)轉(zhuǎn)換問題。

// 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,那么就將設計稿變?yōu)?75px。如果讀取的文件不是vant的文件,那么就將設計稿變?yōu)?50px。這樣就可以避免vant組件在750px下出現(xiàn)樣式縮小的問題了。

同理 這對于其他的移動端UI組件庫同樣有效果。我們只需要改動這行代碼即可

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

至此,我們的viewport的適配就做好了,只需要按照設計稿的比例進行開發(fā)就可以了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容