我們在vue移動端項目中的適配一般都采用rem,但是rem也不是能兼容所有的終端。
隨着viewport單位越來越受到眾多瀏覽器的支持,下面將簡單介紹怎么實現vw的兼容問題,用vw代替rem
當我們采用vue-cli腳手架搭建完項目,安裝所有依賴包之后,用npm run dev啟動后,在根目錄有一個 .postcssrc.js 文件,文件結構如下:

vue-cli默認已經安裝以上三個插件:
postcss-import:相關配置可以點擊這里。主要功有是解決@import引入路徑問題。使用這個插件,可以讓你很輕易的使用本地文件、node_modules或者web_modules的文件。這個插件配合postcss-url讓你引入文件變得更輕松。
postcss-url:相關配置可以點擊這里。該插件主要用來處理文件,比如圖片文件、字體文件等引用路徑的處理。在Vue項目中,vue-loader已具有類似的功能,只需要配置中將vue-loader配置進去。
autoprefixer:用來自動處理瀏覽器前綴的一個插件。如果你配置了postcss-cssnext,其中就已具備了autoprefixer的功能。在配置的時候,未顯示的配置相關參數的話,表示使用的是Browserslist指定的列表參數,你也可以像這樣來指定last 2 versions 或者 > 5%。
Vue-cli默認配置了上述三個PostCSS插件,但我們要完成vw的布局兼容方案,或者說讓我們能更專心的擼碼,還需要配置下面的幾個PostCSS插件:
- postcss-aspect-ratio-mini
- postcss-px-to-viewport
- postcss-write-svg
- postcss-cssnext
- cssnano
- postcss-viewport-units
然后我們安裝
npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --save
安裝成功之后,在項目根目錄下的package.json文件中,可以看到新安裝的依賴包
接下來在.postcssrc.js文件對新安裝的PostCSS插件進行配置:
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
"postcss-aspect-ratio-mini": {},
"postcss-write-svg": {
utf8: false
},
"postcss-cssnext": {},
"postcss-px-to-viewport": {
viewportWidth: 750, // 視窗的寬度,對應的是我們設計稿的寬度,一般是750
viewportHeight: 1334, // 視窗的高度,根據750設備的寬度來指定,一般指定1334,也可以不配置
unitPrecision: 3, // 指定`px`轉換為視窗單位值的小數位數
viewportUnit: "vw", //指定需要轉換成的視窗單位,建議使用vw
selectorBlackList: ['.ignore', '.hairlines'],// 指定不轉換為視窗單位的類,可以自定義,可以無限添加,建議定義一至兩個通用的類名
minPixelValue: 1, // 小於或等於`1px`不轉換為視窗單位,你也可以設置為你想要的值
mediaQuery: false // 允許在媒體查詢中轉換`px`
},
"postcss-viewport-units": {},
"cssnano": {
preset: "advanced",
autoprefixer: false,
"postcss-zindex": false
}
}
}
由於配置文件修改了,所以重新跑一下 npm run dev,然后項目就可以看到了。
簡單介紹上面幾個插件的作用:
postcss-cssnext:其實就是cssnext。該插件可以讓我們使用CSS未來的特性,其會對這些特性做相關的兼容性處理。有關於cssnext的每個特性的操作文檔,可以點擊這里瀏覽。
cssnano:主要用來壓縮和清理CSS代碼。在Webpack中,cssnano和css-loader捆綁在一起,所以不需要自己加載它。詳細文檔可以點擊這里獲取。在cssnano的配置中,使用了preset: "advanced",所以我們需要另外安裝:
npm i cssnano-preset-advanced --save-dev
"cssnano": {
"autoprefixer": false,
"postcss-zindex": false
}
上面的代碼把autoprefixer和postcss-zindex禁掉了。前者是有重復調用,后者是一個討厭的東東。只要啟用了這個插件,z-index的值就會重置為1。這是一個天坑,千萬記得將postcss-zindex設置為false。
postcss-px-to-viewport:要用來把px單位轉換為vw、vh、vmin或者vmax這樣的視窗單位,也是vw適配方案的核心插件之一。在配置中需要配置相關的幾個關鍵參數:
"postcss-px-to-viewport": {
viewportWidth: 750, // 視窗的寬度,對應的是我們設計稿的寬度,一般是750 (如果我們設置的寬度是300px,那么編譯之后的寬度為(300/750*100)=40vw,如果頻寬實際為375px,那么該元素的寬度為(375*0.4)= 150px)
viewportHeight: 1334, // 視窗的高度,根據750設備的寬度來指定,一般指定1334,也可以不配置
unitPrecision: 3, // 指定`px`轉換為視窗單位值的小數位數(很多時候無法整除)
viewportUnit: "vw", // 指定需要轉換成的視窗單位,建議使用vw
selectorBlackList: ['.ignore', '.hairlines'],// 指定不轉換為視窗單位的類,可以自定義,可以無限添加,建議定義一至兩個通用的類名
minPixelValue: 1, // 小於或等於`1px`不轉換為視窗單位,你也可以設置為你想要的值
mediaQuery: false // 允許在媒體查詢中轉換`px`
},
postcss-aspect-ratio-mini:主要用來處理元素容器寬高比。
postcss-write-svg:插件主要用來處理移動端1px的解決方案。該插件主要使用的是border-image和background來做1px的相關處理。
5、偽類 + transform 實現
個人認為偽類+transform是比較完美的方法。利用 :before 或者 :after 實現 border ,並 transform 的 scale 縮小一半,將border 絕對定位。
單條border樣式設置:
.scale-1px{
position: relative;
border:none;
}.scale-1px:after{
content: '';
position: absolute;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
4條border的實現:
.scale-1px{
position: relative;
margin-bottom: 20px;
border:none;
}.scale-1px:after{
content: '';
position: absolute;
top: 0;
left: 0;
border: 1px solid #000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}或者:
.scale-1px:after{
content:'';
position:absolute;
border:1px solid #000;
top:-50%;
right:-50%;
bottom:-50%;
left:-50%;
-webkit-transform:scale(0.5);
transform:scale(0.5);
}

