Vue 3 + Vite 項目 px 轉 vw 完整使用指南

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 驗證方法

  1. 啟動開發服務器

    npm run dev
    
  2. 打開瀏覽器開發者工具

    • 按 F12 打開開發者工具
    • 切換到 Elements/元素面板
    • 查看編譯后的 CSS
  3. 驗證轉換結果

    • 原始 CSS:font-size: 24px
    • 轉換后:font-size: 6.4vw
  4. 測試響應式效果

    • 調整瀏覽器窗口大小
    • 觀察頁面元素是否按比例縮放
    • 使用設備模擬器測試不同屏幕尺寸

📖 配置參數詳細說明

核心參數

參數名類型默認值說明
viewportWidthNumber320設計稿的視口寬度,通常是設計師給出的設計稿寬度
viewportHeightNumber568設計稿的視口高度,一般不需要配置
unitPrecisionNumber5轉換后的單位精度,即小數點后保留幾位
propListArray[‘*’]需要轉換的 CSS 屬性列表
viewportUnitString‘vw’轉換后的視口單位
fontViewportUnitString‘vw’字體相關屬性轉換后的單位

過濾參數

參數名類型默認值說明
selectorBlackListArray[]不需要轉換的選擇器列表
minPixelValueNumber1最小轉換的像素值,小于這個值的 px 不會被轉換
excludeRegExp/Arrayundefined忽略某些文件夾下的文件或特定文件
includeRegExp/Arrayundefined只轉換匹配的文件

高級參數

參數名類型默認值說明
mediaQueryBooleanfalse是否轉換媒體查詢中的 px
replaceBooleantrue是否直接替換屬性值而不添加備用屬性
landscapeBooleanfalse是否添加橫屏時的媒體查詢
landscapeUnitString‘vw’橫屏時使用的單位
landscapeWidthNumber568橫屏時的視口寬度

配置示例

// 移動端項目配置
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 規則排除
  • 選擇器在黑名單中

解決方案

  1. 檢查 vite.config.js 配置是否正確
  2. 確認 CSS 文件路徑沒有被 exclude
  3. 檢查選擇器是否在 selectorBlackList 中
  4. 重啟開發服務器
# 重啟開發服務器
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 視口單位詳解

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/86245.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/86245.shtml
英文地址,請注明出處:http://en.pswp.cn/web/86245.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

setsate()使用詳解原理及注意事項

&#x1f4da; Flutter 狀態管理系列文章目錄 Flutter 狀態管理(setState、InheritedWidget、 Provider 、Riverpod、 BLoC / Cubit、 GetX 、MobX 、Redux) setState() 使用詳解&#xff1a;原理及注意事項 InheritedWidget 組件使用及原理 Flutter 中 Provider 的使用、注…

ffmpeg環境配置

ffmpeg是一個跨平臺功能強大的音視頻處理工具。它不僅能夠進行音視頻的轉換、剪切、合并等操作&#xff0c;還支持多種音視頻格式的解碼和編碼。無論是處理高清視頻還是音頻文件&#xff0c;ffmpg都能提供高效且穩定的服務。其豐富的參數設置和插件支持&#xff0c;使得用戶可以…

Lamp和友點CMS一鍵部署腳本(Rocky linux)

先上傳youdiancms9.3.0.zip包&#xff0c;可以去官網下載 #!/bin/bash #function:install apache mysql php for youdiancms9.3.0ip$(hostname -I | awk {print $1}) yhyoudian passwordyoudian123#檢查是否為root用戶 if [ "$USER" ! "root" ]; thenecho…

Arm架構下麒麟V10桌面版安裝MySQL

Arm架構下麒麟V10桌面版安裝MySQL 文章目錄 Arm架構下麒麟V10桌面版安裝MySQL基礎環境下載安裝包安裝步驟**一、準備工作****二、解壓并配置 MySQL****三、初始化 MySQL****四、啟動 MySQL 服務****五、設置環境變量****六、配置 MySQL****七、驗證安裝****常見問題****總結** …

Science Advances:皮膚附著觸覺貼片,實現多功能和增強的觸覺交互

可穿戴觸覺界面可以通過向皮膚添加觸覺刺激以及傳遞給用戶的視覺和聽覺信息來增強虛擬/增強現實系統中的沉浸式體驗。研究人員介紹了一種平錐介電彈性體致動器&#xff08;FCDEA&#xff09;陣列&#xff0c;該陣列薄而柔軟&#xff0c;能夠響應大面積皮膚上的電壓信號產生時空…

Ntfs!LfsGetLbcb函數分析之nt!CcPreparePinWrite

Ntfs!LfsGetLbcb函數分析之nt!CcPreparePinWrite 第一部分&#xff1a; 1: kd> p Ntfs!LfsPrepareLfcbForLogRecord0x78: f7179d72 e891210000 call Ntfs!LfsGetLbcb (f717bf08) 1: kd> t Ntfs!LfsGetLbcb: f717bf08 6a40 push 40h 1: kd> kc …

面試150 整數轉羅馬數字

思路 建立數字和字符的字典映射表&#xff0c;遍歷映射表做差&#xff0c;將字符添加到結果中&#xff0c;當差為0的時候&#xff0c;break退出循環。返回最后的結果output class Solution:def intToRoman(self, num: int) -> str:if num<1:return num_to_map[(1000,M)…

大模型推理-高通qnn基礎

一、高通ai 軟件的介紹 QualcommAI Engine Direct SDK(qnn) 提供較低級別、高度可定制的統一API&#xff0c;通過單獨的庫加速所有AI加速器核心上的AI模型, 可以直接用于針對特定的加速器核心或從流行的運行時&#xff08;包括Qualcomm Neural Processing SDK、TensorFlow Li…

UE5 - 制作《塞爾達傳說》中林克的技能 - 14 - 技能面板

讓我們繼續《塞爾達傳說》中林克技能的制作&#xff01;&#xff01;&#xff01; UE版本&#xff1a;5.6.0 VS版本&#xff1a;2022 本章節的核心目標&#xff1a;技能面板 先讓我們看一下完成后的效果&#xff1a; 第14章效果 本章節項目鏈接&#xff1a; 通過網盤分享的文件…

用Tensorflow進行線性回歸和邏輯回歸(八)

新的TensorFlow概念 創建簡單的機器學習系統需要學習一些新的概念。 優化器 上兩節介紹的元素已經提示了TensorFlow是如何完成機器學習的。你已學習了如何用張量操作來定義損失函數。缺少的是你不知道如何用TensorFlow進行梯度下降。盡管可以用TensorFlow元素直接用 Python定…

基于python代碼的通過爬蟲方式實現TK下載視頻(2025年6月)

Tk的視頻頁面通常需要登錄才能獲取完整數據,但通過構造匿名游客的請求,我們可以繞過登錄限制,提取視頻的元信息(如標題、ID和播放地址)。核心思路如下: 構造匿名Cookie:通過模擬瀏覽器的請求,獲取Tk服務器分配的游客Cookie。解析網頁:利用BeautifulSoup解析HTML,定位…

火山 RTC 引擎14 設置CB

一、火山RTC引擎集成時,設置CB 1、統一設置 void NRTCEngine::SetByteRtcCBS() {UserPublishStreamCallback callback = [this](const std::string& roomId, const std::string& uid, bytertc::MediaStreamType type) {this->OnSigUserPublishStream(roomId, uid, …

BUUCTF在線評測-練習場-WebCTF習題[極客大挑戰 2019]PHP1-flag獲取、解析

解題思路 打開靶場&#xff0c;提示備份 常見的備份后綴名有.bak&#xff0c;.backup&#xff0c;.zip等等 這里肯定是要掃目錄了&#xff0c;不知道是我的問題還是目錄掃描工具的問題還是BUUCTF的問題&#xff0c;每次要掃目錄能掃出一堆東西來&#xff0c;不管你用什么后綴…

對話云蝠智能:大模型如何讓企業呼叫系統從 “成本中心” 變身 “價值樞紐”?

在人工智能重塑企業服務的浪潮中&#xff0c;云蝠智能&#xff08;南京星蝠科技有限公司旗下品牌&#xff09;以深厚的技術積累和行業實踐&#xff0c;逐步成長為國內智能外呼領域的標桿企業。其發展路徑揭示了技術自主創新與場景深度結合的必然性。 一、技術架構&#xff1a;全…

Python-文件管理

1. Open方法 Python 中的文件操作主要通過內置的 open() 函數來完成&#xff0c;該函數用于打開文件&#xff0c;并返回一個文件對象。通過文件對象&#xff0c;可以進行各種文件操作&#xff0c;如讀取、寫入、關閉等。 使用 open() 方法一定要保證關閉文件對象&#xff0c;即…

高速DIC技術之推進劑樣品在霍普金森桿的高速沖擊下的變形監測與不同材質頭盔在不同沖擊位置下的變形測試-VIC-3D HS非接觸全場動態應變測量系統

工程領域對材料與結構在極端動態載荷下復雜變形行為的測量有強烈的需求&#xff0c;且這種測量必須是精確、全域、非接觸式的&#xff0c;高速DIC技術應運而生并不斷得到發展。 常見動態應用包括&#xff08;但不限于&#xff09;&#xff1a;碰撞測試、爆炸試驗、沖擊試驗、跌…

微算法科技融合Grover算法與統一哈希函數的混合經典-量子算法技術,可在多領域高效提升文本處理效率

隨著數據規模的不斷擴大&#xff0c;尤其是在大數據和人工智能驅動的應用中&#xff0c;這些經典算法的線性復雜度逐漸成為瓶頸。面對數十億級別的文本數據&#xff0c;線性時間的算法仍然難以滿足實時性的要求。此外&#xff0c;經典算法在處理無序或隨機文本時&#xff0c;性…

Spring Boot Security Core

依賴配置&#xff08;Maven&#xff09; xml 復制 下載 運行 <!-- Spring Security Core --> <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>6.2.5<…

【趙渝強老師】OceanBase云平臺OCP

OCP的全稱是OceanBase Cloud Platform&#xff0c;即&#xff1a;OceanBase云平臺。OCP面向有OceanBase管理需求的中小型用戶&#xff0c;提供了基礎的主機管理、OceanBase 集群和租戶運維等能力。在OCP中主要包含兩個組成部分&#xff0c;它們分別是&#xff1a;MetaDB和OCP S…

快速定位Swagger文檔請求地址‘/v2/api-docs‘,發生未知異常.NullPointerException:精準定位+根治方案

問題現場&#xff1a;訪問 http://localhost:8080/v2/api-docs 時日志報錯&#xff1a; 請求地址/v2/api-docs,發生未知異常. java.lang.NullPointerException: nullat springfox.documentation.swagger2.mappers.RequestParameterMapper.bodyParameter(RequestParameterMappe…