在 Vue 项目中使用 vw 实现移动端适配

由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方案。vw的兼容方案可以参阅《如何在Vue项目中使用vw实现移动端适配》一文。

之前一直没有尝试使用 vw 进行移动端适配,这次希望在毕设项目中运用,记录一番步骤,具体的插件用途可查阅参考文章~

安装 PostCSS 插件

1
npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S   

配置插件

.postcssrc.js文件对新安装的PostCSS插件进行配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// https://github.com/michael-ciniawsky/postcss-load-config

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": {
filterRule: rule => rule.nodes.findIndex(i => i.prop === 'content') === -1,
},
"cssnano": {
preset: "advanced",
autoprefixer: false,
"postcss-zindex": false
}
}
}

特别声明:由于cssnextcssnano都具有autoprefixer,事实上只需要一个,所以把默认的autoprefixer删除掉,然后把cssnano中的autoprefixer设置为false

特别声明:

  1. 由于 cssnextcssnano 都具有 autoprefixer ,事实上只需要一个,所以把默认的 autoprefixer 删除掉,然后把 cssnano 中的 autoprefixer 设置为 false

  2. postcss-viewport-units 修改 content ,并不能很好的兼容,会出现以下警告:

    1
    (Emitted value instead of an instance of Error) postcss-viewport-units: ... a:after' already has a 'content' property, give up to overwrite it. 

    解决办法: 如果没有版本需求,可以考虑去掉; 或者进行过滤,具体如下:

    1
    2
    3
    "postcss-viewport-units": {
    filterRule: rule => rule.nodes.findIndex(i => i.prop === 'content') === -1,
    },

使用

在不想要把 px 转换为 vw 的时候,首先在对应的元素(html)中添加配置中指定的类名 .ignore.hairlines (.hairlines 一般用于设置 border-width:0.5px 的元素中):

1
<div class="box ignore"></div>

写 CSS 时

1
2
3
4
5
6
7
8
9
10
11
.ignore {
margin: 10px;
background-color: red;
}
.box {
width: 180px;
height: 300px;
}
.hairlines {
border-bottom: 0.5px solid red;
}

编译出来的 CSS

1
2
3
4
5
6
7
8
9
10
11
.box {
width: 24vw;
height: 40vw;
}
.ignore {
margin: 10px; /*.box元素中带有.ignore类名,在这个类名写的`px`不会被转换*/
background-color: red;
}
.hairlines {
border-bottom: 0.5px solid red;
}

上面解决了pxvw的转换计算。那么在哪些地方可以使用vw来适配我们的页面。根据相关的测试:

  • 容器适配,可以使用vw
  • 文本的适配,可以使用vw
  • 大于1px的边框、圆角、阴影都可以使用vw
  • 内距和外距,可以使用vw

参考文章

如何在Vue项目中使用vw实现移动端适配(转)