在vue開(kāi)發(fā)時(shí),不同窗口寬度下的樣式問(wèn)題一直是個(gè)很頭疼的問(wèn)題,這個(gè)在移動(dòng)端尤為明顯,所以是否有某種方式可以去根據(jù)窗口的寬度或者其他的數(shù)值自動(dòng)調(diào)整頁(yè)面的樣式呢?
首先說(shuō)到頁(yè)面寬度,最先想到的肯定是vw,根據(jù)規(guī)定,一個(gè)窗口的長(zhǎng)度始終為100vw,1vw等于當(dāng)前窗口寬度的1%,所以使用vw確實(shí)可以解決頁(yè)面在不同分辨率下的樣式問(wèn)題,但100vw為100等分,在實(shí)際的開(kāi)發(fā)過(guò)程中確實(shí)過(guò)小了,而在開(kāi)發(fā)微信小程序的時(shí)候,根據(jù)微信的設(shè)置,750rpx就代表一個(gè)窗口的寬度,rpx就是微信小程序中設(shè)置的單位,所以在VUE或者其他前端項(xiàng)目開(kāi)發(fā)中是否也可以設(shè)置某個(gè)單位的功能與rpx是一樣的功能呢?
經(jīng)過(guò)查找,發(fā)現(xiàn)rem的功能可能與rpx的功能相似,rem是根據(jù)HTML根元素的字體大小自動(dòng)設(shè)置的,所以我們只要去設(shè)置HTML根元素字體大小就可以去實(shí)現(xiàn)這個(gè)功能了(關(guān)于rem的概念,這邊只是簡(jiǎn)述,如果不懂,可以自行百度。另外,此處不考慮IE8級(jí)以下和其他暫不支持rem瀏覽器的適配)。
首先在項(xiàng)目public文件夾下的index.html中去編寫(xiě)一個(gè)js方法去計(jì)算根元素的字體大小,具體的思路就是,在頁(yè)面顯示后,自動(dòng)獲取根節(jié)點(diǎn)的寬度,根據(jù)比例去計(jì)算出根節(jié)點(diǎn)的字體大小,再將計(jì)算出來(lái)的字體設(shè)置到根節(jié)點(diǎn)上。具體代碼如下(本案例中的設(shè)定為750rem為窗口的寬度):
<script>
(function (win) {
let designSize = 750; // 窗口的設(shè)計(jì)尺寸,意味著750rem為一個(gè)窗口的寬度。
let html = document.documentElement; // 當(dāng)前窗口對(duì)象
let wW = html.clientWidth; // 當(dāng)前窗口寬度
let rem = wW / designSize; // 計(jì)算比例
document.documentElement.style.fontSize = rem + 'px'; // 設(shè)置根節(jié)點(diǎn)的字體大小
})(window)
</script>
設(shè)置完畢后,新建一個(gè)頁(yè)面進(jìn)行查看效果
<template>
<div class="page">
<div class="row">
</div>
</div>
</template>
<style>
.page{
width: 750rem;
height: 60px;
background: #FFFFFF;
text-align: center;
}
.row{
width: 300rem;
height: 60px;
background: #AAAAAA;
text-align: center;
}
</style>
效果如下:

按理講,以上就已經(jīng)實(shí)現(xiàn)了頁(yè)面上的設(shè)置,但是在實(shí)際開(kāi)發(fā)的過(guò)程中,還是會(huì)遇到瀏覽器的窗口大小變化,而所有的設(shè)置是根據(jù)變化前的數(shù)據(jù)去設(shè)置的,所以我們還需要增加一個(gè)監(jiān)聽(tīng)窗口變化的方法去動(dòng)態(tài)設(shè)置相關(guān)參數(shù)。具體代碼如下:
<script>
(function (win) {
var watch;
function refreshRem() {
let designSize = 1920; // 窗口的設(shè)計(jì)尺寸
let html = document.documentElement; // 當(dāng)前窗口對(duì)象
let wW = html.clientWidth; // 當(dāng)前窗口寬度
let rem = wW * 1 / designSize; // 計(jì)算比例
document.documentElement.style.fontSize = rem + 'px'; // 設(shè)置根節(jié)點(diǎn)的字體大小
}
// 監(jiān)聽(tīng)窗口變化
win.addEventListener('resize', function () {
// 先清除原先未執(zhí)行的設(shè)置,因?yàn)樵O(shè)置設(shè)置了300ms的延時(shí)
clearTimeout(watch);
// 重新設(shè)定新的設(shè)置,300ms后執(zhí)行,延時(shí)是防止獲取窗口變化時(shí)獲取的窗口寬度出錯(cuò)
watch = setTimeout(refreshRem, 300);
}, false);
refreshRem();
})(window)
</script>
為了更加嚴(yán)謹(jǐn),還需要防止在同一個(gè)瀏覽器中切換到其他頁(yè)面上,并在其他頁(yè)面上更改了窗口大小,然后再切換回當(dāng)前頁(yè)面,完整代碼如下:
<script>
(function (win) {
var watch;
function refreshRem() {
let designSize = 1920; // 窗口的設(shè)計(jì)尺寸
let html = document.documentElement; // 當(dāng)前窗口對(duì)象
let wW = html.clientWidth; // 當(dāng)前窗口寬度
let rem = wW * 1 / designSize; // 計(jì)算比例
document.documentElement.style.fontSize = rem + 'px'; // 設(shè)置根節(jié)點(diǎn)的字體大小
}
// 監(jiān)聽(tīng)窗口變化
win.addEventListener('resize', function () {
// 先清除原先未執(zhí)行的設(shè)置,因?yàn)樵O(shè)置設(shè)置了300ms的延時(shí)
clearTimeout(watch);
// 重新設(shè)定新的設(shè)置,300ms后執(zhí)行,延時(shí)是防止獲取窗口變化時(shí)獲取的窗口寬度出錯(cuò)
watch = setTimeout(refreshRem, 300);
}, false);
// 監(jiān)聽(tīng)頁(yè)面顯示或者切換
win.addEventListener('pageshow', function (e) {
// 在頁(yè)面顯示的情況下
if (e.persisted) {
clearTimeout(watch);
watch = setTimeout(refreshRem, 300);
}
}, false);
refreshRem();
})(window)
</script>