ConfigProvider 全域配置 - Vant 4
ConfigProvider 全域配置
⚙️ 介紹
ConfigProvider 就像是 Vant 元件庫的「魔法調色盤」!🎨 它是整個應用的視覺風格指揮官,擁有著神奇的變身能力。無論你想要優雅的深色夜間模式,還是個性十足的彩虹主題,ConfigProvider 都能輕鬆滿足你的需求。
想像一下,只需要輕輕一揮魔法棒,整個應用就能瞬間換裝!從清新的白天模式切換到護眼的深色模式,從預設的藍色主題變身為活力四射的橙色風格,ConfigProvider 讓主題定製變得如此簡單而有趣。它不僅是一個配置工具,更是你打造獨特使用者體驗的得力助手!
📦 引入
透過以下方式來全域註冊元件,更多註冊方式請參考元件註冊。
import { createApp } from'vue';
import { ConfigProvider } from'vant';
const app = createApp();
app.use(ConfigProvider);🌙 深色模式
🌙 開啟深色模式 - 夜貓子的福音
將 ConfigProvider 元件的 theme 屬性設定為 dark,就像給你的應用戴上了一副時尚的墨鏡!😎
深色模式就像是應用的「夜間守護者」,它會溫柔地將所有 Vant 元件包裹在柔和的深色調中。無論是深夜加班的程式設計師,還是喜歡在暗光環境下使用手機的使用者,都能享受到這種護眼又酷炫的視覺體驗。一鍵開啟,整個世界瞬間變得優雅而神秘!
值得注意的是,开启 Vant 的深色模式只会影响 Vant 组件的 UI,并不会影响全局的文字颜色或背景颜色,你可以参考以下 CSS 来设置一些全局样式:
.van-theme-darkbody { color: #f5f5f5; background-color: black; }🔄 動態切換 - 變色龍般的靈活
透過動態設定 theme 屬性,你的應用就擁有了變色龍般的超能力!🦎 可以在陽光明媚的淺色風格和星空璀璨的深色風格之間自由穿梭。
就像魔法師揮舞魔法棒一樣,使用者可以根據當前環境、心情或時間來選擇最適合的主題。白天工作時選擇清爽的淺色模式提升專注度,夜晚休閒時切換到溫柔的深色模式保護視力。這種貼心的設計讓使用者體驗更加人性化!
exportdefault { setup() { const theme = ref('light'); setTimeout(() => { theme.value = 'dark'; }, 1000); return { theme }; }, };🎨 定制主題 - 你的專屬調色盤
🌈 介紹 - 解鎖無限創意可能
Vant 元件就像一座精心設計的「樂高積木城堡」,每個元件都透過豐富的 CSS 變數 來構建其視覺外觀。這些 CSS 變數就像是城堡的「魔法寶石」,只要替換不同顏色的寶石,整座城堡就能煥然一新!
透過巧妙地覆蓋這些 CSS 變數,你可以輕鬆實現個性化主題定制、即時動態切換主題等令人驚豔的效果。無論是企業品牌色、節日主題色,還是使用者個人喜好色,都能完美呈現!
範例
以 Button 元件為例,查看元件的樣式,可以看到 .van-button--primary 類名上存在以下變數:
.van-button--primary {
color: var(--van-button-primary-color);
background-color: var(--van-button-primary-background);
}这些变量的默认值被定义在 :root 节点上,HTML 里的所有子节点都可以访问到这些变量:
:root { --van-white: #fff; --van-blue: #1989fa; --van-button-primary-color: var(--van-white); --van-button-primary-background: var(--van-primary-color); }自定義 CSS 變數
透過 CSS 覆蓋
你可以直接在程式碼中覆蓋這些 CSS 變數,Button 元件的樣式會隨之發生改變:
/* 添加这段样式后,Primary Button 会变成红色 */
:root:root { --van-button-primary-background: red; }注意:为什么要写两个重复的
:root?由于 vant 中的主题变量也是在
:root下声明的,所以在有些情况下会由于优先级的问题无法成功覆盖。通过:root:root可以显式地让你所写内容的优先级更高一些,从而确保主题变量的成功覆盖。
透過 ConfigProvider 覆蓋
ConfigProvider 元件提供了覆蓋 CSS 變數的能力,你需要在根節點包裹一個 ConfigProvider 元件,並透過 theme-vars 屬性來配置一些主題變數。
import { ref, reactive } from'vue';
export default {
setup() {
const rate = ref(4);
const slider = ref(50);
// themeVars 内的值会被转换成对应 CSS 变量
// // 比如 sliderBarHeight 会转换成 `--van-slider-bar-height`
const themeVars = reactive({ rateIconFullColor: '#07c160', sliderBarHeight: '4px', sliderButtonWidth: '20px', sliderButtonHeight: '20px', sliderActiveBackground: '#07c160', buttonPrimaryBackground: '#07c160', buttonPrimaryBorderColor: '#07c160', });
return { rate, slider, themeVars, };
},
};CSS 變數生效範圍
預設情況下,themeVars 產生的 CSS 變數是設定在元件根節點上的,因此只會影響它的子元件的樣式,不會影響整個頁面。
你可以透過 theme-vars-scope 屬性來修改 CSS 變數的生效範圍。比如將 theme-vars-scope 設定為 global,此時 themeVars 產生的 CSS 變數會設定到 HTML 的根節點,並對整個頁面內的所有元件生效。
在 TypeScript 中使用
在 TypeScript 中定義 themeVars 時,建議使用 Vant 提供的 ConfigProviderThemeVars 類型,可以提供完善的類型提示:
import type { ConfigProviderThemeVars } from'vant';
const themeVars: ConfigProviderThemeVars = { sliderBarHeight: '4px', };結合深色模式與 CSS 變數
如果需要單獨定義深色模式或淺色模式下的 CSS 變數,可以使用 theme-vars-dark 和 theme-vars-light 屬性。
theme-vars-dark: 僅在深色模式下生效的 CSS 變數,優先級高於theme-vars中定義的變數。theme-vars-light: 僅在淺色模式下生效的 CSS 變數,優先級高於theme-vars中定義的變數。
範例
以下方的 buttonPrimaryBackground 變數為例, 在深色模式下的值為 blue,在淺色模式下的值為 green。
import { ref, reactive } from'vue';
export default {
setup() {
const themeVars = reactive({ buttonPrimaryBackground: 'red' });
const themeVarsDark = reactive({ buttonPrimaryBackground: 'blue' });
const themeVarsLight = reactive({ buttonPrimaryBackground: 'green' });
return { themeVars, themeVarsDark, themeVarsLight, };
},
};使用類名
此外,你也可以使用 .van-theme-light 和 .van-theme-dark 這兩個類名選擇器來單獨修改淺色或深色模式下的基礎變數和元件變數。
.van-theme-light { --van-white: white; }
.van-theme-dark { --van-white: black; }主題變數
變數類型
Vant 中的 CSS 變數分為 基礎變數 和 元件變數。元件變數會繼承基礎變數,因此在修改基礎變數後,會影響所有相關的元件。
修改變數
CSS 變數存在繼承關係,元件變數會尋找最近的父級基礎變數進行繼承。
因此修改基礎變數存在一定限制,你需要使用 :root 選擇器或 ConfigProvider 元件的 global 模式來修改基礎變數。否則,元件變數可能會無法正確繼承基礎變數。
以 --van-primary-color 這個基礎變數為例:
- 可以透過
:root選擇器修改:
:root { --van-primary-color: red; }- 可以透過 ConfigProvider 元件的 global 模式修改:
- 不可以透過 ConfigProvider 元件預設的
local模式修改:
對於元件變數,則沒有上述限制,可以透過任意方式修改。
基礎變數列表
下面是所有的基礎變數:
// Color
Palette--van-black: #000;
Palette--van-white: #fff;
--van-gray-1: #f7f8fa;
--van-gray-2: #f2f3f5;
--van-gray-3: #ebedf0;
--van-gray-4: #dcdee0;
--van-gray-5: #c8c9cc;
--van-gray-6: #969799;
--van-gray-7: #646566;
--van-gray-8: #323233;
--van-red: #ee0a24;
--van-blue: #1989fa;
--van-orange: #ff976a;
--van-orange-dark: #ed6a0c;
--van-orange-light: #fffbe8;
--van-green: #07c160;
// Gradient
//Colors
--van-gradient-red: linear-gradient(to right, #ff6034, #ee0a24);
//Colors
--van-gradient-orange: linear-gradient(to right, #ffd01e, #ff8917);
// Component
//Colors
--van-primary-color: var(--van-blue);
--van-success-color: var(--van-green);
--van-danger-color: var(--van-red);
--van-warning-color: var(--van-orange);
--van-text-color: var(--van-gray-8);
--van-text-color-2: var(--van-gray-6);
--van-text-color-3: var(--van-gray-5);
--van-active-color: var(--van-gray-2);
--van-active-opacity: 0.6;
--van-disabled-opacity: 0.5;
//Colors
--van-background: var(--van-gray-1);
--van-background-2: var(--van-white);
// Padding
--van-padding-base: 4px;
--van-padding-xs: 8px;
--van-padding-sm: 12px;
--van-padding-md: 16px;
--van-padding-lg: 24px;
--van-padding-xl: 32px;
// Font
--van-font-size-xs: 10px;
--van-font-size-sm: 12px;
--van-font-size-md: 14px;
--van-font-size-lg: 16px;
--van-font-bold: 600;
--van-line-height-xs: 14px;
--van-line-height-sm: 18px;
--van-line-height-md: 20px;
--van-line-height-lg: 22px;
--van-base-font: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
--van-price-font: Avenir-Heavy, PingFang SC, Helvetica Neue, Arial, sans-serif;
// Animation
--van-duration-base: 0.3s; --van-duration-fast: 0.2s; --van-ease-out: ease-out; --van-ease-in: ease-in;
// Border
--van-border-color: var(--van-gray-3);
--van-border-width: 1px;
--van-radius-sm: 2px;
--van-radius-md: 4px;
--van-radius-lg: 8px;
--van-radius-max: 999px;你可以在各個元件文檔底部的表格中查看元件變數。
API
Props
| 參數 | 說明 | 類型 | 預設值 |
|---|---|---|---|
| theme | 主題風格,設定為 dark 來開啟深色模式,全域生效 | ConfigProviderTheme | light |
| theme-vars | 自定義主題變數,局部生效 | object | - |
| theme-vars-dark | 僅在深色模式下生效的主題變數,優先級高於 theme-vars | object | - |
| theme-vars-light | 僅在淺色模式下生效的主題變數,優先級高於 theme-vars | object | - |
| theme-vars-scope | 預設僅影響子元件的樣式,設定為 global 整個頁面生效 | ConfigProviderThemeVarsScope | local |
| tag | 根節點對應的 HTML 標籤名 | string | div |
| z-index | 設定所有彈窗類元件的 z-index,該屬性對全域生效 | number | 2000 |
| icon-prefix | 所有圖示的類名前綴,等同於 Icon 元件的 class-prefix 屬性 | string | van-icon |
類型定義
元件匯出以下類型定義:
import type { ConfigProviderProps, ConfigProviderTheme, ConfigProviderThemeVars, ConfigProviderThemeVarsScope, } from'vant';🎯 最佳實踐
🎨 主題設計原則
- 保持一致性 - 確保整個應用的主題風格統一協調
- 考慮可存取性 - 選擇對比度足夠的顏色組合,確保文字清晰可讀
- 響應使用者偏好 - 支援系統主題跟隨,提供手動切換選項
- 效能最佳化 - 避免頻繁切換主題,合理使用快取機制
🔧 主題變數管理技巧
// 推薦:集中管理主題變數
const lightTheme = {
primaryColor: '#1989fa',
successColor: '#07c160',
warningColor: '#ff976a',
dangerColor: '#ee0a24'
}
const darkTheme = {
primaryColor: '#3291ff',
successColor: '#4fc08d',
warningColor: '#fcbd71',
dangerColor: '#f56c6c'
}
// 動態切換主題
const currentTheme = computed(() =>
isDark.value ? darkTheme : lightTheme
)📱 響應式主題適配
/* 跟隨系統主題 */
@media (prefers-color-scheme: dark) {
:root {
--van-primary-color: #3291ff;
--van-background: #1a1a1a;
}
}
/* 行動端適配 */
@media (max-width: 768px) {
:root {
--van-font-size-md: 16px;
--van-padding-md: 20px;
}
}❓ 常見問題解決
🔍 主題變數不生效?
問題:設定了主題變數但樣式沒有改變 解決方案:
- 檢查 CSS 變數名是否正確(注意
--van-前綴) - 確認變數作用域設定(local vs global)
- 使用
:root:root提高優先級
🌙 深色模式閃爍問題
問題:切換深色模式時出現白屏閃爍 解決方案:
/* 預設深色背景避免閃爍 */
html {
background-color: #1a1a1a;
color-scheme: dark light;
}🎨 自定義主題色不統一
問題:部分元件沒有應用自定義主題色 解決方案:
- 使用基礎變數而非元件變數
- 檢查元件是否支援該主題變數
- 考慮使用 CSS 類名覆蓋
💡 進階用法範例
🌈 多主題切換系統
<template>
<ConfigProvider :theme-vars="currentThemeVars">
<div class="theme-selector">
<button
v-for="theme in themes"
:key="theme.name"
@click="switchTheme(theme)"
:class="{ active: currentTheme === theme.name }"
>
{{ theme.label }}
</button>
</div>
<YourApp />
</ConfigProvider>
</template>
<script setup>
const themes = [
{ name: 'default', label: '預設藍', vars: { primaryColor: '#1989fa' } },
{ name: 'green', label: '清新綠', vars: { primaryColor: '#07c160' } },
{ name: 'orange', label: '活力橙', vars: { primaryColor: '#ff976a' } },
{ name: 'purple', label: '神秘紫', vars: { primaryColor: '#7232dd' } }
]
const currentTheme = ref('default')
const currentThemeVars = computed(() =>
themes.find(t => t.name === currentTheme.value)?.vars || {}
)
const switchTheme = (theme) => {
currentTheme.value = theme.name
// 可選:儲存使用者偏好
localStorage.setItem('preferred-theme', theme.name)
}
</script>🎭 節日主題自動切換
// 根據日期自動應用節日主題
const getSeasonalTheme = () => {
const now = new Date()
const month = now.getMonth() + 1
const day = now.getDate()
// 春節主題
if (month === 1 || month === 2) {
return { primaryColor: '#ff4757', successColor: '#ffa502' }
}
// 聖誕主題
if (month === 12) {
return { primaryColor: '#2ed573', dangerColor: '#ff4757' }
}
// 預設主題
return {}
}🎨 設計靈感
🌟 熱門主題配色方案
科技藍 - 專業、可信賴
css--van-primary-color: #0066cc; --van-success-color: #00cc66;溫暖橙 - 友好、活力
css--van-primary-color: #ff6b35; --van-warning-color: #ffa726;優雅紫 - 創意、高端
css--van-primary-color: #6c5ce7; --van-success-color: #00b894;
🎯 行業主題建議
- 金融類應用:穩重藍色 + 安全綠色
- 電商類應用:活力橙色 + 促銷紅色
- 教育類應用:知識藍色 + 成長綠色
- 醫療類應用:醫療藍色 + 健康綠色
📚 相關文件
- Icon 圖示 - 了解圖示元件的使用方法
- Style 內建樣式 - 查看 Vant 的內建樣式變數
- 進階用法 - 學習更多元件註冊方式
- 快速上手 - 從零開始使用 Vant
🔗 延伸閱讀
- CSS 自定義屬性 (變數) - MDN 官方文件
- 深色模式設計指南 - Apple 設計規範
- Material Design 主題系統 - Google 設計規範
- 無障礙設計色彩對比度 - 線上對比度檢測工具