最近可能需要做一个移动端的H5项目,了解到虽然lib-filexible比较常用,但是viewport越来越流行,所以想尝试使用vw来做移动端适配,顺便学习一下
vw适配主要依赖于postcss-px-to-viewport这个插件,自动根据屏幕宽度把px转化为vw单位,以达到适配的目的
目前我的配置如下,亲测可以正常运行
1,先下载相关插件(注意版本匹配,我是自己一个个试出来的最终匹配版本)
npm i postcss-px-to-viewport postcss-aspect-ratio-mini postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --save
还差什么插件,根据你vue-cli的版本不同也不一样,到时候根据运行时吧哦哦哦错提示再自行下载,基本也就这些。
至于每个插件的作用是什么,可以自行百度,这样可以了解的更详细
然后运行下面代码
npm i cssnano-preset-advanced --save-dev
不然会报错。
2,在根目录下新建postcss.config.js文件,并配置如下:
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
"postcss-aspect-ratio-mini": {},
"postcss-write-svg": {
utf8: false
},
"postcss-cssnext": {},
"postcss-px-to-viewport": {
viewportWidth: 750px, // (Number) The width of the viewport.
viewportHeight: 1334px, // (Number) The height of the viewport.
unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
viewportUnit: 'vw', // (String) Expected units.
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.
// exclude: [/node_modules/]
},
"postcss-viewport-units":{},
"cssnano": {
"cssnano-preset-advanced": {
zindex: false,
autoprefixer: false
}
}
}
}
vw适配并不兼容所有浏览器,我们可以用viewport-units-buggyfill来解决兼容问题,使用方法如下
在index.html中引入cdn链接
<script src="//g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></script>
并在body后新建script标签,并加上如下代码
window.onload = function () {
window.viewportUnitsBuggyfill.init({
hacks: window.viewportUnitsBuggyfillHacks
});
}
然后在全局样式中加上如下代码:原因可自行百度viewport-units-buggyfill,文档中很清楚
img {
content: normal !important;
}
如果加上这个样式后出现报错或者警告如下:
already has a 'content' property, give up to overwrite it.
解决方案:
配置.postcssrc.js的postcss-viewport-units为:
'postcss-viewport-units': {
filterRule: rule => rule.selector.includes('::after') && rule.selector.includes('::before') && rule.selector.includes(':after') && rule.selector.includes(':before')
}
或者
'postcss-viewport-units': {
filterRule: rule => rule.nodes.findIndex(i => i.prop === "content") === -1
}
这样就可开心地使用vw布局了
3.配置vant
1,npm i vant --save
2,按需引入
直接按照vant文档按需引入即可
也可能会出现样式无效的情况,如果怎么样都无法生效,那就看一下vue.config.js,如果requireModuleExtension的值设置为false,则会导致第三方组件库的样式不生效,vue.config.js设置如下:
css: {
extract: true, // 是否使用css分离插件 ExtractTextPlugin
sourceMap: false, // 开启 CSS source maps?
loaderOptions: {
less: {
lessOptions: {
javascriptEnabled: true,
modifyVars: {
/* less 变量覆盖,用于自定义主题 */
'primary-color': '#1890FF',
'link-color': '#1890FF',
'border-radius-base': '4px'
}
}
}
},
requireModuleExtension: true // 启用 CSS modules for all css / pre-processor files.
},
然后更改postcss.config.js文件的配置如下
const path = require('path');
module.exports = ({ file }) => {
const designWidth = file.dirname.includes(path.join('node_modules', 'vant')) ? 375 : 750;
const designHeight = file.dirname.includes(path.join('node_modules', 'vant')) ? 667 : 1334;
return {
"plugins": {
"postcss-import": {},
"postcss-url": {},
"postcss-aspect-ratio-mini": {},
"postcss-write-svg": {
utf8: false
},
"postcss-cssnext": {},
"postcss-px-to-viewport": {
viewportWidth: designWidth, // (Number) The width of the viewport.
viewportHeight: designHeight, // (Number) The height of the viewport.
unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
viewportUnit: 'vw', // (String) Expected units.
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.
// exclude: [/node_modules/]
},
"postcss-viewport-units":{},
"cssnano": {
"cssnano-preset-advanced": {
zindex: false,
autoprefixer: false
}
}
}
}
}
因为vant团队的是根据375px的设计稿去做的,理想视口宽度为375px,一般我们的是设计稿的宽度为750px,如果不想为了适应vant而把设计稿修改为375px的,那就可以使用如上的方法设置。
.postcss.config.js文件,它除了暴露一个对象,也可以暴露一个函数,无论暴露什么,在webpack运行时,都会被我们配置的海量文件读取并执行。
当暴露函数时有一个好处,可以拿到webpack运行的当前执行文件的信息,那就可以区别设置视口的宽度啦。
注:使用某个框架前,最好花时间熟读文档,如果实在没时间,也要先看看快速上手和开发指南,你会发现很多彩蛋,这不是在浪费时间,而是为了让你少踩很多坑。以上不止是我个人的使用经验,踩了很多坑,也在网上借鉴了很多大神的文章,最终正常运行了,特意记录一下,希望能对大家有所帮助!
有问题可以私信我哦,知无不言!
至此,我们就可以愉快地进行移动端开发啦!