Vant 默认使用
px作为样式单位,如果需要使用viewport单位 (vw, vh, vmin, vmax),推荐使用 postcss-px-to-viewport 进行转换。
# 1. 安装依赖 pnpm add -D postcss-px-to-viewport-8-plugin
安装
postcss-px-to-viewport时,当前版本 v1.1.1 长期未更新,include 在 vue3 项目中实测不生效。不设置或者将其设置成
include: undefined如果控制台会报以下错误:postcss-px-to-viewport: postcss.plugin was deprecated.Migration guide: 可以通过将
postcss-px-to-viewport换成postcss-px-to-viewport-8-plugin解决
# 2. vite.config.ts 配置
| import pxtovw from 'postcss-px-to-viewport-8-plugin'; | |
| css: { | |
| devSourcemap: true, // 在开发过程中是否启用 sourcemap。 | |
| postcss: { | |
| plugins: [ | |
| pxtovw({ | |
| unitToConvert: 'px', // 要转化的单位 | |
| viewportWidth: 375, // UI 设计稿的宽度 | |
| unitPrecision: 6, // 转换后的精度,即小数点位数 | |
| propList: ['*'], // 指定转换的 css 属性的单位,* 代表全部 css 属性的单位都进行转换 | |
| viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认 vw | |
| fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认 vw | |
| selectorBlackList: [], // 指定不转换为视窗单位的类名, | |
| minPixelValue: 1, // 默认值 1,小于或等于 1px 则不进行转换 | |
| mediaQuery: true, // 是否在媒体查询的 css 代码中也进行转换,默认 false | |
|                     //replace: true, // 是否直接更换属性值,而不添加备用属性 | |
| exclude: [/^(?!.*node_modules\/vant)(?!.*__uno\.css)/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件 | |
|                     //include: undefined, // 如果设置了 include,那将只有匹配到的文件才会被转换 | |
| landscape: false // 是否处理横屏情况 | |
| }) | |
|         ] | |
|     } | |
| }, | 
注意 :
- postcss-px-to-viewport对- 内联css样式,- 外联css样式,- 内嵌css样式有效,对 js- 动态css无效。 所以要动态改变 css 展示效果的话,要使用静态的 class 定义变化样式,通过 js 改变 dom 元素的- class实现样式变化
- vue 模板中的 px 单位不会被转换,如需转换请使用 postcss-style-px-to-viewport工具
# 3. 解决 vant 和 postcss-px-to-viewport 的配合
一般我们的设计稿都是 750,而 vant 的设计稿是 375,这就出现一种冲突。以 750 执行的话,则 vant 组件会变小
- # postcss-px-to-viewport 移动端适配
在 vant 库里,我们依然用 375 的设计稿的宽度,其它的文件我们依然用 750 设计稿的宽度
| //postcss.config.js | |
| const path = require('path'); | |
| module.exports = ({webpack }) => { | |
| const designWidth = webpack.resourcePath.includes(path.join('node_modules', 'vant')) ? 375 : 750; | |
| return { | |
| plugins: { | |
| 'postcss-px-to-viewport': { | |
| viewportWidth: designWidth, // 视窗的宽度,对应的是我们设计稿的宽度,一般是 750 | |
|                 //viewportHeight: 1334, // 视窗的高度,根据 750 设备的宽度来指定,一般指定 1334,也可以不配置 | |
| }, | |
|         } | |
|     } | |
| } | 
| //vite.config.ts | |
| pxToViewport({ | |
| unitToConvert: 'px', // 要转化的单位 | |
| viewportWidth: file => (join(file).includes(join('node_modules', 'vant')) ? 375 : 750), // UI 设计稿的宽度 | |
| unitPrecision: 6, // 转换后的精度,即小数点位数 | |
| propList: ['*'], // 指定转换的 css 属性的单位,* 代表全部 css 属性的单位都进行转换 | |
| viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认 vw | |
| fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认 vw | |
| selectorBlackList: [], // 指定不转换为视窗单位的类名, | |
| minPixelValue: 1, // 默认值 1,小于或等于 1px 则不进行转换 | |
| mediaQuery: true, // 是否在媒体查询的 css 代码中也进行转换,默认 false | |
|     //replace: true, // 是否直接更换属性值,而不添加备用属性 | |
| exclude: [/^(?!.*node_modules\/vant)(?!.*__uno\.css)/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件 | |
|     //include: undefined, // 如果设置了 include,那将只有匹配到的文件才会被转换 | |
| landscape: false // 是否处理横屏情况 | |
| }) | 
注意:这里使用
path.join('node_modules', 'vant')是因为适应不同的操作系统,在 mac 下结果为node_modules/vant,而在 windows 下结果为node_modules\vant
Vant 组件的设计稿尺寸是 375px,可用通过覆盖:root 下的 Vant 的 css 变量中 px 单位的方式,对 Vant 组件做适配
