02-移动端vm适配方案
vm是新出的移动端适配方案,提到vm我们就不得不说rem,我们首先来看下两者的区别
rem布局
方案:
规定750px 尺寸下,我们设置跟字体html的font-size: 100px, 即1rem = 100px
这样750px 尺寸的psd图片上,量得的宽度/高度, 如150px, 写到css中的时候,需要经过换算
150px/100px = 1.5rem
1
我们随着设备尺寸变化,按比例750px/100px 修改html的根字体大小
rem随着跟字体变化,则页面上所有用rem单位的元素大小也跟着变化
监听resize方法,设备宽度变化时,计算得到根字体大小,并修改html的根字体,实现响应式布局
VM布局
vm是移动端支持较好的css属性,设备宽度 = 100vm,浏览器会自动帮我们计算1vm, 2vm…等等大小
我们在上面的rem布局中,750px宽度下,设置根字体html的font-size: 100px,之后需要用js按比例动态计算根字体的大小,然而用js没有用css修改的速度快,这里我们保持750px/100px的比例
设备宽度=100vm
1vm = 750px/100px = 7.5px
100px = 1/7.5*100vm
1
2
3
vm不需要自己再动态计算根字体,页面渲染速度更快,所以我们采取vm来适配。
vue-cli3中我们可以引入postcss-px-to-viewport插件
npm install postcss-loader postcss-px-to-viewport --save-dev
因为插件的配置选项中有个exclude选项,它的值只支持正则表达式,但是正则表达式再json中是不允许的,所以不要配置在package.json中,要配置在vue.config.js里
module.exports = {
css: {
loaderOptions: {
postcss: {
plugins: [
require("postcss-px-to-viewport")({
unitToConvert: "px",
viewportWidth: 375, // 视窗的宽度,对应的是我们设计稿的宽度,一般是750
unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
propList: [
"*"
],
viewportUnit: "vw", // 指定需要转换成的视窗单位,建议使用vw
fontViewportUnit: "vw",
selectorBlackList: [], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
mediaQuery: false, // 允许在媒体查询中转换`px`
replace: true,
exclude: /(\/|\\)(node_modules)(\/|\\)/,
})
]
}
}
}
}
配置完成后重启下项目,就会发现,页面元素已经可以自适应啦。
但是会存在一个问题,postcss只能转换css,不能转行内样式,这个时候我们可以利用一个插件style-vm-loader(github地 https://github.com/hyy1115/style-vw-loader)
npm install style-vw-loader --save-dev
vue-cli3项目,在vue.config.js中配置
{
chainWebpack: (config) => {
config.module
.rule('vue')
.test(/\.vue$/)
.use('style-vw-loader')
.loader('style-vw-loader')
}
}
另一种方案:
1.安装依赖
npm install postcss-px-to-viewport -D
2.修改 .postcssrc.js
将根目录下 .postcssrc.js 文件修改如下
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
plugins: {
autoprefixer: {
overrideBrowserslist: ['Android 4.1', 'iOS 7.1', 'Chrome > 31', 'ff > 31', 'ie >= 8']
},
'postcss-px-to-viewport': {
viewportWidth: 375, // 视窗的宽度,对应的是我们设计稿的宽度,一般是750
unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
selectorBlackList: ['.ignore', '.hairlines'], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
mediaQuery: false // 允许在媒体查询中转换`px`
}
}
}
3.删除原来的 rem 相关代码
src/main.js 删除如下代码
// 移动端适配
import 'lib-flexible/flexible.js'
package.json 删除如下代码
"lib-flexible": "^0.3.2",
"postcss-pxtorem": "^5.1.1",