1. 程式人生 > >vue移動端的適配rem和vw記錄

vue移動端的適配rem和vw記錄

在接觸移動端開發的時候,適配是必須要解決的一個問題。個人在開發過程中,也是邊做邊學,使用了一些常用的解決方案,這裡一一列舉出來:

前提:移動端的適配更多關注的是寬度的適配,也就是說元素在不同裝置上通過改變自身寬度來實現在頁面的比例一樣,這樣佈局就不會亂掉
1.百分比代替px

在最開始做移動端頁面時,能想到的只有使用百分比,簡單直接

    <style>
        body{
            margin: 0;
            padding: 0;
        }
        .box{
            width: 80%;
            background-color: #b0b0b0;
        }
        .child{
            width: 20%;
            height: 50px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="child"></div>
    </div>
</body>

我們在iphone5和iphone6plus裝置上測試,box父元素的寬度是裝置寬度的80%,child子元素寬度是box的20%

測量後發現iphone5上box元素寬度是256px,子元素寬度51.19px,iphone6plus上box元素寬度331.19px,子元素寬度66.23px,

元素實現了根據寬度的自動調節來保持佈局一致(元素的畫素精度略有偏差)

優點:簡單、方便

缺點:不適用根據設計稿來開發,並且由於子元素繼承了父元素,如果改變了父元素的百分比,子元素的寬度改變也不好控制。另外高度無法適配,侷限性較大

2.使用媒體查詢

在接觸bootstrap的時候,在使用裡面提供的元件時,瞭解到css的媒體查詢來實現適配

<style>
        body{
            margin: 0;
            padding: 0;
        }
        .box{
            background-color: #b0b0b0;
        }
        .child{
            background-color: yellow;
            height: 50px;
        }
        @media screen and (max-width: 414px){
            .box{
                width: 331.2px;
            }
            .child{
                width: 66.24px;
            }
        }
        @media screen and (max-width: 320px){
            .box{
                width: 256px;
            }
            .child{
                width: 52px;
            }
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="child"></div>
    </div>
</body>

我們使用媒體查詢,根據裝置寬度分別設定了iphone6plus和iphone5下box和child元素的寬度,從而保證了父元素和子元素的比例一致

優點:可以實現各個移動端適配,並且可以設定高度和其他各種樣式,在製作響應式佈局時具有強大的功能

缺點:只是為了適配來使用媒體查詢,比較麻煩,需要寫很多的判斷,殺雞用牛刀的感覺....

3.使用rem

在學習vue專案開發時,大佬們提出了px轉rem,來解決適配問題,一個預載入器px2rem-loader

我們可以自己動手寫一個這樣的功能,來實現px自動轉rem。核心是要用到scss的function功能,以及給document元素的DOMContentLoaded事件新增一個事件處理程式,動態計算根節點font-size

用rem和vw方法時,我們需要一個參考標準,也就是設計稿要先按照iphone5、iphone6、iphone6plus等等中的一個做為標準。

比如我們以iphone6為標準 375*667

我們建立一個.scss樣式檔案

@function px2rem($px){
    $rem: 37.5px;
    @return ($px/$rem) + rem;
}
.box{
    width: px2rem(375px);
    height: px2rem(100px);
    background: #b0b0b0;
    border-bottom: 1px solid red;
}

聲明瞭一個px2rem的函式,$rem變數叫做rem基準值,也是根元素的font-size。這裡是根據375/10計算來的,除以10是方便計算。設計稿一般會放大2倍(這個根據裝置的dpr),所以我們在樣式裡的寬度要除2,比如設計稿中的box元素是全屏寬750px,那麼樣式中box的寬度就要設定為375px。

我們接著再建立一個Adjust.js的檔案

var dpr = window.devicePixelRatio;
document.addEventListener('DOMContentLoaded', () => {
    document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
})

這裡是動態設定html元素的font-size,注意這裡除10,是和之前$rem那裡關聯的。如果那裡設定3.75,那麼這裡就要除以100

我們引入Adjust.js和.scss樣式檔案,在不同裝置下檢視

可以看到box元素的寬度適配了iphone6和iphone5。

裝置的dpr不一樣,比如iphone6是2,iphone6plus和iphoneX是3,那麼如果美術每次給了dpr不一樣的設計稿,我們還要計算後才能在樣式中寫入,豈不是很麻煩?(其實一般都是iphone6,放大2倍,這裡只是引入一個技巧...)

我們是否可以根據設計稿大小直接寫,不用計算?

記得寫H5頁面的head中都會有這麼一句:

<meta name="viewport" content="width=device-width, initial-scale=1.0">initial-scale=1.0的意思是縮放為1。我們通過js改變這個縮放不就可以了?比如iphone6下,我們把initial-scale設定成1/2,這樣當我們把box的寬度寫成750,那麼實際顯示就是375。

通過window.devicePixelRatio可以獲取到裝置的dpr

Adjust.js檔案修改一下:

/* 動態設定fontSize */
var dpr = window.devicePixelRatio;
document.addEventListener('DOMContentLoaded', () => {
    document.getElementsByTagName('html')[0].style.fontSize = window.innerWidth / 10 + 'px';
})
document.getElementsByTagName('meta')['viewport'].setAttribute('content', 'initial-scale=' + 1/dpr + ', maximum-scale=' + 1/dpr + ', minimum-scale=' + 1/dpr + ', user-scalable=no,width = device-width');

.scss檔案也做下對應修改:

@function px2rem($px){
    $rem: 75px;
    @return ($px/$rem) + rem;
}
.box{
    width: px2rem(750px);
    height: px2rem(100px);
    background: #b0b0b0;
    border-bottom: 1px solid red;
}

我們直接寫設計稿上box的寬度,基準值那裡改成75,大功告成~

4.使用vw

差不多目前學到的適配方法這麼多,這裡只是記錄下,積累知識。