1.首先是依赖/插件的安装
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 --S
安装成功之后,在项目根目录下的package.json文件中,可以看到新安装的依赖包:
"dependencies": {
"cssnano": "^3.10.0",
"postcss-aspect-ratio-mini": "0.0.2",
"postcss-cssnext": "^3.1.0",
"postcss-px-to-viewport": "0.0.3",
"postcss-viewport-units": "^0.1.3",
"postcss-write-svg": "^3.0.1",
"vue": "^2.5.2",
"vue-router": "^3.0.1"
},
cssnano
然后是cssnano
的补充安装
cssnano主要用来压缩和清理CSS代码。在Webpack中,cssnano
和css-loader
捆绑在一起,所以不需要自己加载它。
npm i cssnano-preset-advanced --save-dev
"cssnano": {
autoprefixer: false,
"postcss-zindex": false
}
上面的代码把autoprefixer和postcss-zindex禁掉了。前者是有重复调用,后者会导致css的zIndex
失效,只要启用了这个插件,z-index的值就会重置为1。这是一个天坑,千万记得将postcss-zindex设置为false。
postcss-px-to-viewport
postcss-px-to-viewport
插件主要用来把px
单位转换为vw
、vh
、vmin
或者vmax
这样的视窗单位,也是vw适配方案
的核心插件之一。
在配置中需要配置相关的几个关键参数:
"postcss-px-to-viewport": {
viewportWidth: 375, // 视窗的宽度,对应的是我们设计稿的宽度,一般是750
viewportHeight: 667, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
unitPrecision: 5, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
selectorBlackList: ['.ignore', '.hairlines'], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
mediaQuery: false // 允许在媒体查询中转换`px`
},
整合起来的.postcssrc.js文件内容配置如下,大家安装完上面所有依赖后,可直接替换成当前内容即可,详情请看注释:
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
"postcss-aspect-ratio-mini": {},
"postcss-write-svg": {
utf8: false
},
"postcss-cssnext": {},
"postcss-px-to-viewport": {
viewportWidth: 375, // 视窗的宽度,对应的是我们设计稿的宽度,一般是750
viewportHeight: 667, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
unitPrecision: 5, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
selectorBlackList: ['.ignore', '.hairlines'], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
mediaQuery: false // 允许在媒体查询中转换`px`
},
"postcss-viewport-units": {
filterRule: rule => rule.selector.indexOf('::after') === -1 && rule.selector.indexOf('::before') === -1 && rule.selector.indexOf(':after') === -1 && rule.selector.indexOf(':before') === -1
},
"cssnano": {
"preset": [
"advanced",{
autoprefixer:false,
zindex: false,
}
]
}
}
}
至此配置好了,下面说说使用效果和一些注意点:
2.使用效果
那么我们就可以根据设计图上的px值直接转换成对应的vw值。在实际中不需要进行任何的计算,直接在代码中写px,比如:
.test {
border: .5px solid black;
border-bottom-width: 4px;
font-size: 14px;
line-height: 20px;
position: relative;
}
编译出来的CSS:
.test {
border: .5px solid #000; /*像素大于1px才会被转换*/
border-bottom-width: .533vw;
font-size: 1.867vw;
line-height: 2.667vw;
position: relative;
}
在不想要把px转换为vw的时候,首先在对应的元素(html)中添加配置中指定的类名.ignore或.hairlines(.hairlines一般用于设置border-width:0.5px的元素中):
编译出来的CSS:
.box {
width: 24vw;
height: 40vw;
}
.ignore {
margin: 10px; /*.box元素中带有.ignore类名,在这个类名写的`px`不会被转换*/
background-color: red;
}
.hairlines {
border-bottom: 0.5px solid red;
}
谢谢大家浏览到这里! 处理好移动端vw适配问题后,也许我们还需要使用公共样式less方便之后样式的维护,有兴趣或者有需要的请继续查看我另一篇 App.vue引入全局公共样式common.less
--by Affandi ⊙▽⊙