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.完成
前言
前段時間我的移動端適配解決方案[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ā)就可以了。