如果你還對使用vw做移動端頁面適配不了解,這里推薦大漠老師的兩篇文章
再聊移動端頁面的適配和如何在Vue項目中使用vw實現(xiàn)移動端適配
隨著視口單位被眾多瀏覽器所支持,我們現(xiàn)在完全可以使用vw來做移動端的適配問題。下面就介紹一下Vue2.x 中使用vw實現(xiàn)移動端頁面適配的步驟。代碼
前提
你已經(jīng)了解vue cli來構(gòu)建項目。無論使用vue cli 2.x 還是3.x 版本,如果你了解webpack配置,那么過程都是大同小異。首先我們初始化一個項目:
vue init webpack vue-mb-vw
進入項目:
cd vue-mb-vw
啟動項目:
npm run dev
1. 安裝一些PostCSS插件
在項目的根目錄下有一個.postcssrc.js,默認情況下已經(jīng)安裝了以下幾個插件:
postcss-import
postcss-import主要功有是解決@import引入路徑問題。使用這個插件,可以讓你很輕易的使用本地文件、node_modules文件
postcss-url
該插件主要用來處理文件,比如圖片文件、字體文件等引用路徑的處理。在Vue項目中, vue-loader 已具有類似的功能
autoprefixer
autoprefixer插件是用來自動處理瀏覽器前綴的一個插件
為了完成vw的布局兼容方案并簡化我們的工作,還需要安裝配置下面的幾個PostCSS插件:
- postcss-px-to-viewport
- postcss-cssnext
- cssnano
- postcss-aspect-ratio-mini
- postcss-write-svg
- postcss-viewport-units
npm i postcss-px-to-viewport postcss-cssnext cssnano postcss-aspect-ratio-mini postcss-write-svg postcss-viewport-units --save-dev
接下來在.postcssrc.js文件對新安裝的PostCSS插件進行配置:
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// "autoprefixer": {},
"postcss-aspect-ratio-mini": {},
"postcss-write-svg": {
utf8: false
},
"postcss-cssnext": {},
"postcss-px-to-viewport": {
viewportWidth: 750, // (Number) The width of the viewport.
unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
viewportUnit: 'vw', // (String) Expected units.
propList:['*','!font','!font-size'],
selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px.
minPixelValue: 1, // (Number) Set the minimum pixel value to replace.
mediaQuery: false // (Boolean) Allow px to be converted in media queries.
},
"postcss-viewport-units":{},
"cssnano": {
preset: "advanced",
autoprefixer: false,
"postcss-zindex": false
}
}
}
注意:由于cssnext和cssnano都具有autoprefixer。所以需要把默認的autoprefixer刪除掉,然后把cssnano中的autoprefixer設(shè)置為false,我們使用cssnext的autoprefixer。
將viewportWidth設(shè)為我們視覺稿的尺寸,這里使用750px的視覺稿
postcss-px-to-viewport
postcss-px-to-viewport插件主要用來把px單位轉(zhuǎn)換為vw、vh、vmin或者vmax這樣的視窗單位,也是vw適配方案的核心插件之一。配置我們參考官網(wǎng)
postcss-cssnext
postcss-cssnext其實就是cssnext。該插件可以讓我們使用CSS未來的特性,其會對這些特性做相關(guān)的兼容性處理。
cssnano
cssnano主要用來壓縮和清理CSS代碼。在Webpack中,cssnano和 css-loader捆綁在一起,所以不需要自己加載它。不過你也可以使postcss-loader顯式的使用cssnano。
在cssnano的配置中,使用了preset: "advanced",所以我們需要另外安裝cssnano-preset-advanced:
npm i cssnano-preset-advanced --save-dev
cssnano集成了一些其他的PostCSS插件,如果你想禁用cssnano中的某個插件的時候,可以像下面這樣操作:
"cssnano": {
autoprefixer: false,
"postcss-zindex": false
}
上面的代碼把autoprefixer和postcss-zindex禁掉了。前者是有重復(fù)調(diào)用,后者只要啟用了,z-index的值就會重置為1,我們需要禁用。
postcss-aspect-ratio-mini
postcss-aspect-ratio-mini主要用來處理元素容器寬高比。在實際使用的時候,具有一個默認的結(jié)構(gòu),用法可以去github查看。
postcss-write-svg
postcss-write-svg插件主要用來處理移動端1px的解決方案。該插件主要使用的是border-image和background來做1px的相關(guān)處理。
postcss-viewport-units
postcss-viewport-units插件主要是給CSS的屬性添加content的屬性,配合viewport-units-buggyfill庫給vw、vh、vmin和vmax做適配的操作。
這是實現(xiàn)vw布局必不可少的一個插件,因為少了這個插件,這將是一件痛苦的事情。
2. 兼容vw
讓瀏覽器兼容視口單位的最終的解決方案就是使用viewport-units-buggyfill
viewport-units-buggyfill主要有兩個JavaScript文件:viewport-units-buggyfill.js和viewport-units-buggyfill.hacks.js。
(1)在vue項目中的index.html引入它們:
<script src="http://g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></script>
當(dāng)然你也可以使用其他CDN,或者使用npm安裝
(2)調(diào)用viewport-units-buggyfill:
<script>
window.onload = function () {
window.viewportUnitsBuggyfill.init({
hacks: window.viewportUnitsBuggyfillHacks
});
}
</script>
(3)在使用了視口單位地方,添加content
在你的CSS中,只要使用到了viewport的單位(vw、vh、vmin或vmax )地方,需要在樣式中添加content:
ul {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
font-size: 18px;
list-style-type: none;
padding:20px;
/* hack to engage viewport-units-buggyfill */
content: "viewport-units-buggyfill; padding: 2.667vw";
}
如果每次都需要手動書寫,會極大地增加我們的工作量。這個時候就需要前面提到的postcss-viewport-units 插件。這個插件將讓你無需關(guān)注content的內(nèi)容,插件會自動幫你處理。
viewport-units-buggyfill還提供了其他的功能,詳細的這里不闡述了。
3.常見問題
(1)遇到不想px轉(zhuǎn)換為vw的地方,可以添加指定的類名像.ignore。然后在 "postcss-px-to-viewport"插件配置中的selectorBlackList屬性添加這個類名即可
(2)使用了ui框架的,需要避免px轉(zhuǎn)vw??梢栽?"postcss-px-to-viewport"插件配置中的exclude屬性添加ui框架的目錄,將其排除在外
(3)Viewport Units Buggyfill添加的content也會引起一定的副作用。比如
The
contenthack may not work well on<img>and other replaced elements, even though it should compute tocontent: normal;on regular elements. If you find yourself in such a situation, this may be a way out:
img {
content: normal !important;
}
This buggyfill only works on stylesheets! viewport units used in
styleattributes are not resolved.
The buggyfill can easily trip over files host on different origins (requiring CORS) and relative URLs to images/fonts/… within stylesheets. #11