Vue 3 + Vite 项目 px 转 vw 完整使用指南
🚀 第一步:插件安装
1.1 安装命令
# 使用 npm 安装
npm install postcss-px-to-viewport-8-plugin --save-dev# 或使用 yarn 安装
yarn add postcss-px-to-viewport-8-plugin --dev# 或使用 pnpm 安装
pnpm add postcss-px-to-viewport-8-plugin --save-dev
1.2 验证安装
安装完成后,检查 package.json
文件中是否包含该依赖:
{"devDependencies": {"postcss-px-to-viewport-8-plugin": "^1.2.5"}
}
⚙️ 第二步:Vite 配置方法
2.1 方法一:直接在 vite.config.js 中配置(推荐)
import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import postcssViewport from "postcss-px-to-viewport-8-plugin";export default defineConfig({plugins: [vue()],resolve: {alias: {"@": fileURLToPath(new URL("./src", import.meta.url)),},},css: {postcss: {plugins: [postcssViewport({// 设计稿的视口宽度viewportWidth: 1920,// 设计稿的视口高度(可选)viewportHeight: 1080,// 转换后的单位精度unitPrecision: 3,// 需要转换的CSS属性,* 表示所有属性propList: ["*"],// 转换后的视口单位viewportUnit: "vw",// 字体相关属性转换后的单位fontViewportUnit: "vw",// 不需要转换的选择器selectorBlackList: [".ignore", ".hairlines"],// 最小转换的像素值,小于这个值的px不会被转换minPixelValue: 1,// 是否转换媒体查询中的pxmediaQuery: false,// 是否直接替换属性值而不添加备用属性replace: true,// 忽略某些文件夹下的文件或特定文件exclude: [/node_modules/, /\.min\.css$/],// 只转换匹配的文件(可选)include: undefined,// 是否添加横屏时的媒体查询landscape: false,// 横屏时使用的单位landscapeUnit: "vw",// 横屏时的视口宽度landscapeWidth: 568,}),],},},
});
2.2 方法二:使用 postcss.config.js 配置文件
如果项目不使用 ES 模块(package.json 中没有"type": “module”),可以创建 postcss.config.js
:
module.exports = {plugins: {"postcss-px-to-viewport-8-plugin": {viewportWidth: 375,viewportHeight: 667,unitPrecision: 3,propList: ["*"],viewportUnit: "vw",fontViewportUnit: "vw",selectorBlackList: [".ignore", ".hairlines"],minPixelValue: 1,mediaQuery: false,replace: true,exclude: [/node_modules/, /\.min\.css$/],include: undefined,landscape: false,landscapeUnit: "vw",landscapeWidth: 568,},},
};
然后在 vite.config.js
中引用:
export default defineConfig({// ...其他配置css: {postcss: "./postcss.config.js",},
});
🧪 第三步:使用示例和验证方法
3.1 创建测试组件
创建 src/components/PxToVwDemo.vue
:
<template><div class="demo-container"><!-- 头部区域 --><header class="header"><div class="header-content"><h1 class="main-title"><span class="title-icon">📐</span>px转vw响应式演示</h1><p class="subtitle">现代化响应式设计工具与演示平台</p></div><div class="header-bg"></div></header><!-- 控制面板 --><section class="control-panel"><div class="panel-card"><h3 class="panel-title">🎛️ 设计稿基准设置</h3><div class="design-width-selector"><buttonv-for="width in designWidths":key="width.value":class="['width-btn', { active: currentDesignWidth === width.value }]"@click="setDesignWidth(width.value)">{{ width.label }}</button></div></div><div class="panel-card"><h3 class="panel-title">🧮 实时转换计算器</h3><div class="calculator"><div class="input-group"><label>px值:</label><inputv-model.number="pxInput"type="number"placeholder="输入px值"class="calc-input"/></div><div class="conversion-result"><span class="result-label">转换结果:</span><span class="result-value">{{ convertedVw }}vw</span><span class="result-desc">(基于{{ currentDesignWidth }}px设计稿)</span></div></div></div></section><!-- 视口信息面板 --><section class="viewport-info"><div class="info-card"><div class="info-item"><span class="info-label">当前视口</span><span class="info-value">{{ viewportWidth }}px</span></div><div class="info-item"><span class="info-label">1vw等于</span><span class="info-value">{{ (viewportWidth / 100).toFixed(2) }}px</span></div><div class="info-item"><span class="info-label">缩放比例</span><span class="info-value">{{ (viewportWidth / currentDesignWidth).toFixed(3) }}</span></div><div class="info-item"><span class="info-label">设备类型</span><span class="info-value">{{ deviceType }}</span></div></div></section><!-- UI组件演示区域 --><section class="demo-section"><h2 class="section-title">🎨 UI组件演示</h2><!-- 按钮演示 --><div class="demo-card"><h3 class="demo-title">按钮组件</h3><div class="button-demo"><button class="btn btn-primary">主要按钮</button><button class="btn btn-secondary">次要按钮</button><button class="btn btn-success">成功按钮</button><button class="btn btn-warning">警告按钮</button><button class="btn btn-danger">危险按钮</button></div></div><!-- 表单演示 --><div class="demo-card"><h3 class="demo-title">表单组件</h3><div class="form-demo"><div class="form-group"><label class="form-label">用户名</label><input type="text" class="form-input" placeholder="请输入用户名" /></div><div class="form-group"><label class="form-label">邮箱地址</label><input type="email" class="form-input" placeholder="请输入邮箱" /></div><div class="form-group"><label class="form-label">个人简介</label><textarea class="form-textarea" placeholder="请输入个人简介"></textarea></div></div></div><!-- 卡片演示 --><div class="demo-card"><h3 class="demo-title">卡片组件</h3><div class="card-demo"><div class="feature-card"><div class="card-icon">🚀</div><h4 class="card-title">高性能</h4><p class="card-desc">优化的响应式转换算法,确保最佳性能表现</p></div><div class="feature-card"><div class="card-icon">🎯</div><h4 class="card-title">精确转换</h4><p class="card-desc">精确的px到vw转换,支持多种设计稿基准</p></div><div class="feature-card"><div class="card-icon">📱</div><h4 class="card-title">响应式</h4><p class="card-desc">完美适配各种屏幕尺寸和设备类型</p></div></div></div><!-- 忽略转换演示 --><div class="demo-card"><h3 class="demo-title">转换控制演示</h3><div class="ignore-demo"><div class="comparison-group"><div class="comparison-item"><h4>固定尺寸 (ignore)</h4><div class="fixed-box">120px × 80px</div><p class="desc">使用 px-to-viewport-ignore 注释</p></div><div class="comparison-item"><h4>响应式尺寸</h4><div class="responsive-box">120px × 80px → vw</div><p class="desc">自动转换为vw单位</p></div></div></div></div></section><!-- 交互演示区域 --><section class="interactive-section"><h2 class="section-title">🎮 交互演示</h2><div class="demo-card"><h3 class="demo-title">Hover效果演示</h3><div class="hover-demo"><div class="hover-card" v-for="i in 6" :key="i"><span class="hover-text">悬停卡片 {{ i }}</span></div></div></div></section></div>
</template><script>import { ref, computed, onMounted, onUnmounted } from 'vue'export default {name: 'PxToVwDemo',setup() {// 响应式数据const viewportWidth = ref(window.innerWidth)const currentDesignWidth = ref(375)const pxInput = ref(24)// 设计稿宽度选项const designWidths = ref([{ label: '移动端 375px', value: 375 },{ label: '平板 750px', value: 750 },{ label: '桌面 1920px', value: 1920 },])// 计算属性const convertedVw = computed(() => {if (!pxInput.value || !currentDesignWidth.value) return '0.00'return ((pxInput.value / currentDesignWidth.value) * 100).toFixed(2)})const deviceType = computed(() => {const width = viewportWidth.valueif (width < 768) return '📱 移动设备'if (width < 1024) return '📟 平板设备'return '🖥️ 桌面设备'})// 方法const updateViewportWidth = () => {viewportWidth.value = window.innerWidth}const setDesignWidth = width => {currentDesignWidth.value = width}// 生命周期onMounted(() => {window.addEventListener('resize', updateViewportWidth)})onUnmounted(() => {window.removeEventListener('resize', updateViewportWidth)})return {viewportWidth,currentDesignWidth,pxInput,designWidths,convertedVw,deviceType,setDesignWidth,}},}
</script><style scoped>/* 全局样式 */* {box-sizing: border-box;}/* 容器样式 */.demo-container {min-height: 100vh;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);padding: 20px;font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;}/* 头部样式 */.header {position: relative;text-align: center;margin-bottom: 40px;overflow: hidden;border-radius: 20px;}.header-content {position: relative;z-index: 2;padding: 40px 20px;background: rgba(255, 255, 255, 0.1);backdrop-filter: blur(10px);border: 1px solid rgba(255, 255, 255, 0.2);}.header-bg {position: absolute;top: 0;left: 0;right: 0;bottom: 0;background: linear-gradient(45deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));animation: float 6s ease-in-out infinite;}.main-title {font-size: 32px;font-weight: 700;color: white;margin: 0 0 10px 0;text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);}.title-icon {display: inline-block;margin-right: 10px;font-size: 36px;animation: bounce 2s infinite;}.subtitle {font-size: 16px;color: rgba(255, 255, 255, 0.9);margin: 0;font-weight: 300;}/* 控制面板样式 */.control-panel {display: grid;grid-template-columns: 1fr 1fr;gap: 20px;margin-bottom: 30px;}.panel-card {background: rgba(255, 255, 255, 0.95);backdrop-filter: blur(10px);border-radius: 16px;padding: 24px;box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);border: 1px solid rgba(255, 255, 255, 0.2);transition:transform 0.3s ease,box-shadow 0.3s ease;}.panel-card:hover {transform: translateY(-5px);box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);}.panel-title {font-size: 18px;font-weight: 600;color: #2c3e50;margin: 0 0 16px 0;}/* 设计稿宽度选择器 */.design-width-selector {display: flex;gap: 8px;flex-wrap: wrap;}.width-btn {padding: 8px 16px;border: 2px solid #e1e8ed;border-radius: 20px;background: white;color: #657786;font-size: 12px;font-weight: 500;cursor: pointer;transition: all 0.3s ease;white-space: nowrap;}.width-btn:hover {border-color: #667eea;color: #667eea;transform: scale(1.05);}.width-btn.active {background: linear-gradient(135deg, #667eea, #764ba2);border-color: #667eea;color: white;box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);}/* 计算器样式 */.input-group {margin-bottom: 16px;}.input-group label {display: block;font-size: 14px;font-weight: 500;color: #374151;margin-bottom: 6px;}.calc-input {width: 100%;padding: 12px 16px;border: 2px solid #e5e7eb;border-radius: 12px;font-size: 16px;transition: all 0.3s ease;background: white;}.calc-input:focus {outline: none;border-color: #667eea;box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);}.conversion-result {padding: 16px;background: linear-gradient(135deg, #f8fafc, #e2e8f0);border-radius: 12px;border-left: 4px solid #667eea;}.result-label {font-size: 14px;color: #64748b;font-weight: 500;}.result-value {font-size: 24px;font-weight: 700;color: #667eea;margin: 0 8px;font-family: 'Courier New', monospace;}.result-desc {font-size: 12px;color: #94a3b8;}/* 视口信息样式 */.viewport-info {margin-bottom: 30px;}.info-card {background: rgba(255, 255, 255, 0.95);backdrop-filter: blur(10px);border-radius: 16px;padding: 24px;box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);border: 1px solid rgba(255, 255, 255, 0.2);display: grid;grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));gap: 20px;}.info-item {text-align: center;padding: 16px;background: linear-gradient(135deg, #f8fafc, #e2e8f0);border-radius: 12px;transition: transform 0.3s ease;}.info-item:hover {transform: scale(1.05);}.info-label {display: block;font-size: 12px;color: #64748b;font-weight: 500;margin-bottom: 8px;text-transform: uppercase;letter-spacing: 0.5px;}.info-value {display: block;font-size: 18px;font-weight: 700;color: #1e293b;font-family: 'Courier New', monospace;}/* 演示区域样式 */.demo-section {margin-bottom: 40px;}.section-title {font-size: 28px;font-weight: 700;color: white;text-align: center;margin-bottom: 30px;text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);}.demo-card {background: rgba(255, 255, 255, 0.95);backdrop-filter: blur(10px);border-radius: 16px;padding: 24px;margin-bottom: 24px;box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);border: 1px solid rgba(255, 255, 255, 0.2);transition:transform 0.3s ease,box-shadow 0.3s ease;}.demo-card:hover {transform: translateY(-5px);box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);}.demo-title {font-size: 20px;font-weight: 600;color: #2c3e50;margin: 0 0 20px 0;padding-bottom: 12px;border-bottom: 2px solid #e2e8f0;}/* 按钮演示样式 */.button-demo {display: flex;gap: 12px;flex-wrap: wrap;}.btn {padding: 12px 24px;border: none;border-radius: 8px;font-size: 14px;font-weight: 600;cursor: pointer;transition: all 0.3s ease;text-transform: uppercase;letter-spacing: 0.5px;}.btn:hover {transform: translateY(-2px);box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);}.btn-primary {background: linear-gradient(135deg, #667eea, #764ba2);color: white;}.btn-secondary {background: linear-gradient(135deg, #6c757d, #495057);color: white;}.btn-success {background: linear-gradient(135deg, #28a745, #20c997);color: white;}.btn-warning {background: linear-gradient(135deg, #ffc107, #fd7e14);color: white;}.btn-danger {background: linear-gradient(135deg, #dc3545, #e83e8c);color: white;}/* 表单演示样式 */.form-demo {display: grid;gap: 20px;}.form-group {display: flex;flex-direction: column;}.form-label {font-size: 14px;font-weight: 600;color: #374151;margin-bottom: 8px;}.form-input,.form-textarea {padding: 12px 16px;border: 2px solid #e5e7eb;border-radius: 8px;font-size: 16px;transition: all 0.3s ease;background: white;}.form-input:focus,.form-textarea:focus {outline: none;border-color: #667eea;box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);}.form-textarea {min-height: 80px;resize: vertical;}/* 卡片演示样式 */.card-demo {display: grid;grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));gap: 20px;}.feature-card {background: linear-gradient(135deg, #f8fafc, #e2e8f0);border-radius: 12px;padding: 24px;text-align: center;transition: all 0.3s ease;border: 2px solid transparent;}.feature-card:hover {transform: translateY(-5px);border-color: #667eea;box-shadow: 0 8px 25px rgba(102, 126, 234, 0.15);}.card-icon {font-size: 48px;margin-bottom: 16px;display: block;}.card-title {font-size: 18px;font-weight: 600;color: #2c3e50;margin: 0 0 12px 0;}.card-desc {font-size: 14px;color: #64748b;line-height: 1.5;margin: 0;}/* 忽略转换演示样式 */.ignore-demo {padding: 20px;background: linear-gradient(135deg, #f8fafc, #e2e8f0);border-radius: 12px;}.comparison-group {display: grid;grid-template-columns: 1fr 1fr;gap: 24px;}.comparison-item {text-align: center;}.comparison-item h4 {font-size: 16px;font-weight: 600;color: #2c3e50;margin: 0 0 16px 0;}.fixed-box {width: 120px; /* px-to-viewport-ignore */height: 80px; /* px-to-viewport-ignore */background: linear-gradient(135deg, #95a5a6, #7f8c8d);color: white;display: flex;align-items: center;justify-content: center;border-radius: 8px;font-size: 12px;font-weight: 600;margin: 0 auto 12px auto;box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);}.responsive-box {width: 120px;height: 80px;background: linear-gradient(135deg, #e67e22, #d35400);color: white;display: flex;align-items: center;justify-content: center;border-radius: 8px;font-size: 12px;font-weight: 600;margin: 0 auto 12px auto;box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);transition: transform 0.3s ease;}.responsive-box:hover {transform: scale(1.05);}.desc {font-size: 12px;color: #64748b;margin: 0;}/* 交互演示样式 */.interactive-section {margin-bottom: 40px;}.hover-demo {display: grid;grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));gap: 16px;}.hover-card {height: 100px;background: linear-gradient(135deg, #667eea, #764ba2);border-radius: 12px;display: flex;align-items: center;justify-content: center;color: white;font-weight: 600;cursor: pointer;transition: all 0.3s ease;position: relative;overflow: hidden;}.hover-card::before {content: '';position: absolute;top: 0;left: -100%;width: 100%;height: 100%;background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);transition: left 0.5s ease;}.hover-card:hover {transform: translateY(-5px) scale(1.05);box-shadow: 0 12px 30px rgba(102, 126, 234, 0.3);}.hover-card:hover::before {left: 100%;}.hover-text {position: relative;z-index: 1;}/* 动画定义 */@keyframes float {0%,100% {transform: translateY(0px);}50% {transform: translateY(-10px);}}@keyframes bounce {0%,20%,50%,80%,100% {transform: translateY(0);}40% {transform: translateY(-10px);}60% {transform: translateY(-5px);}}/* 响应式设计 */@media (max-width: 768px) {.control-panel {grid-template-columns: 1fr;}.comparison-group {grid-template-columns: 1fr;}.card-demo {grid-template-columns: 1fr;}.button-demo {justify-content: center;}.main-title {font-size: 24px;}.section-title {font-size: 22px;}}@media (max-width: 480px) {.demo-container {padding: 16px;}.panel-card,.demo-card {padding: 16px;}.hover-demo {grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));}.design-width-selector {justify-content: center;}.width-btn {font-size: 11px;padding: 6px 12px;}}
</style>
3.2 在主应用中使用
在 src/App.vue
中引入演示组件:
<template><div id="app"><PxToVwDemo /></div>
</template><script>
import PxToVwDemo from "./components/PxToVwDemo.vue";export default {name: "App",components: {PxToVwDemo,},
};
</script>
3.3 验证方法
-
启动开发服务器:
npm run dev
-
打开浏览器开发者工具:
- 按 F12 打开开发者工具
- 切换到 Elements/元素面板
- 查看编译后的 CSS
-
验证转换结果:
- 原始 CSS:
font-size: 24px
- 转换后:
font-size: 6.4vw
- 原始 CSS:
-
测试响应式效果:
- 调整浏览器窗口大小
- 观察页面元素是否按比例缩放
- 使用设备模拟器测试不同屏幕尺寸
📖 配置参数详细说明
核心参数
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
viewportWidth | Number | 320 | 设计稿的视口宽度,通常是设计师给出的设计稿宽度 |
viewportHeight | Number | 568 | 设计稿的视口高度,一般不需要配置 |
unitPrecision | Number | 5 | 转换后的单位精度,即小数点后保留几位 |
propList | Array | [‘*’] | 需要转换的 CSS 属性列表 |
viewportUnit | String | ‘vw’ | 转换后的视口单位 |
fontViewportUnit | String | ‘vw’ | 字体相关属性转换后的单位 |
过滤参数
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
selectorBlackList | Array | [] | 不需要转换的选择器列表 |
minPixelValue | Number | 1 | 最小转换的像素值,小于这个值的 px 不会被转换 |
exclude | RegExp/Array | undefined | 忽略某些文件夹下的文件或特定文件 |
include | RegExp/Array | undefined | 只转换匹配的文件 |
高级参数
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
mediaQuery | Boolean | false | 是否转换媒体查询中的 px |
replace | Boolean | true | 是否直接替换属性值而不添加备用属性 |
landscape | Boolean | false | 是否添加横屏时的媒体查询 |
landscapeUnit | String | ‘vw’ | 横屏时使用的单位 |
landscapeWidth | Number | 568 | 横屏时的视口宽度 |
配置示例
// 移动端项目配置
postcssViewport({viewportWidth: 375, // iPhone 6/7/8 宽度unitPrecision: 3, // 保留3位小数propList: ["*"], // 转换所有属性selectorBlackList: [".ignore", ".hairlines"],minPixelValue: 1, // 1px及以上才转换mediaQuery: false, // 不转换媒体查询exclude: [/node_modules/], // 忽略第三方库
});// 桌面端项目配置
postcssViewport({viewportWidth: 1200, // 桌面端设计稿宽度unitPrecision: 2, // 保留2位小数propList: ["width", "height", "margin*", "padding*"],selectorBlackList: [".pc-fixed"],minPixelValue: 2, // 2px及以上才转换mediaQuery: true, // 转换媒体查询exclude: [/node_modules/, /\.min\.css$/],
});
🔧 常见问题和解决方案
问题 1:插件不生效,px 没有被转换
可能原因:
- 插件配置错误
- 文件被 exclude 规则排除
- 选择器在黑名单中
解决方案:
- 检查 vite.config.js 配置是否正确
- 确认 CSS 文件路径没有被 exclude
- 检查选择器是否在 selectorBlackList 中
- 重启开发服务器
# 重启开发服务器
npm run dev
问题 2:第三方组件库样式被错误转换
解决方案:
postcssViewport({// 排除第三方组件库exclude: [/node_modules/, /element-plus/, /ant-design-vue/, /vant/],// 或使用选择器黑名单selectorBlackList: [".el-", // Element Plus".ant-", // Ant Design".van-", // Vant],
});
问题 3:1px 边框被转换导致在某些设备上消失
解决方案:
postcssViewport({minPixelValue: 2, // 小于2px的不转换selectorBlackList: [".hairlines"], // 1px边框专用类
});
/* 1px边框专用样式 */
.hairlines {border: 1px solid #eee; /* 不会被转换 */
}
问题 4:字体在大屏幕上过大
解决方案:
postcssViewport({viewportWidth: 375,// 使用CSS clamp()限制字体大小范围// 或者设置最大视口宽度maxDisplayWidth: 750, // 自定义参数,需要额外处理
});
/* 手动使用clamp()限制字体大小 */
.title {font-size: clamp(16px, 4.267vw, 24px);
}
问题 5:开发环境和生产环境表现不一致
解决方案:
// 环境特定配置
const isProduction = process.env.NODE_ENV === "production";postcssViewport({viewportWidth: 375,unitPrecision: isProduction ? 2 : 5, // 生产环境减少精度replace: isProduction, // 生产环境直接替换exclude: isProduction ? [/node_modules/, /\.min\.css$/] : [/node_modules/],
});
🎯 最佳实践
1. 设计稿规范
- 与设计师确认设计稿宽度(推荐 375px 或 750px)
- 统一设计稿的单位和标注方式
- 建立设计稿到代码的转换规范
2. 代码规范
/* 推荐:使用语义化的尺寸 */
.container {width: 375px;
} /* 全宽 */
.half-width {width: 187.5px;
} /* 半宽 */
.quarter {width: 93.75px;
} /* 四分之一宽 *//* 推荐:建立间距系统 */
.spacing-xs {margin: 4px;
} /* 最小间距 */
.spacing-sm {margin: 8px;
} /* 小间距 */
.spacing-md {margin: 16px;
} /* 中等间距 */
.spacing-lg {margin: 24px;
} /* 大间距 */
.spacing-xl {margin: 32px;
} /* 最大间距 */
3. 团队协作
- 在项目 README 中说明 px 转 vw 的使用规范
- 建立代码审查检查清单
- 提供设计稿到 vw 的转换工具或计算器
4. 性能优化
postcssViewport({// 只转换必要的属性propList: ["width","height","margin*","padding*","font-size","line-height","top","bottom","left","right",],// 减少不必要的精度unitPrecision: 3,// 排除不需要转换的文件exclude: [/node_modules/, /\.min\.css$/, /vendor/],
});
📚 相关资源
- postcss-px-to-viewport-8-plugin GitHub
- PostCSS 官方文档
- Vite CSS 配置文档
- CSS 视口单位详解