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標籤刪掉,
在這裏插入圖片描述
完美解決,讓我們的css1px等於了設備的物理像素,但是爲什麼作者說lib-flexible這個東西已放棄呢,有圖有真相
在這裏插入圖片描述
他說存在一定的問題,也沒說什麼問題,
那我們繼續引入第三方插件庫試試,
在這裏插入圖片描述

大家會清楚的看到這第三方插件庫怎麼這麼小啊,爲什麼呢?
我們看下mintUI的源碼

在這裏插入圖片描述
再看下他裏面的單位
在這裏插入圖片描述

大家可以看到咱們在這歡樂的動態生成viewport,但是第三方庫並沒有,人家寫死的,除了一些flex或百分比佈局,其他都是按邏輯像素走的px,放到我們這個按物理像素走的區域上能不小嗎?大家不信可以試一下dpr爲1的設備,算了,我還是截個圖吧

在這裏插入圖片描述
進一步驗證了我們的結果,
作者爲什麼放棄這個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是寫死的,也就是都是按照邏輯像素走的,按照正常思維是沒錯的,大家可以看下截圖
在這裏插入圖片描述
看着沒問題啊,但是你看到的這些是用flex佈局或者百分比佈局的,我們來看下具體到px的,

在這裏插入圖片描述
這個確定、取消的寬度比之前小了一倍,爲什麼呢?
在不轉rem之前,插件裏面寫死的是40px;而我們轉過之後40/75rem,
在iphone6下1rem=37.5px,算出來的就是19.9999px,也就是小了一倍,
出現這種問題的原因當然是我們的rem是按照750設計稿轉的,然而mintUI裏面並沒有和我們的一致,也許人家的適配已經轉過了結果就是40px;而我們這裏又轉一遍,所以就出現了 postcss-px2rem-exclude這個插件,他的目的是不轉第三方庫,完美解決我們的問題。
到這裏我們的移動端適配就介紹完了,這個適配就是按照設備邏輯像素也叫獨立像素的適配。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章