目錄
- 效果預覽
- 完整代碼
- 我遇到的BUG
- 問題代碼
- BUG1:暗黑模式下內容區不變成深色
- BUG2:光亮模式下的左右區域是深色
- 補充知識
- ConfigProvider是什么?
- Ant Design中的theme如何使用?
- theme 配置的常見字段
- 主題算法
- 通過 useToken 獲取主題
效果預覽
暗黑模式:
光亮模式:
完整代碼
import React, { useState } from 'react';
import { Breadcrumb, Layout, Menu, theme, ConfigProvider, Switch } from 'antd';const { Header, Content, Footer } = Layout;const items = [{ key: '0', label: '測試' }];const App: React.FC = () => {const [isDarkMode, setIsDarkMode] = useState(false);return (<ConfigProvidertheme={{algorithm: isDarkMode ? theme.darkAlgorithm : theme.defaultAlgorithm,}}>{/* useToken 必須在 ConfigProvider 作用域內 */}<ThemeWrapper isDarkMode={isDarkMode} setIsDarkMode={setIsDarkMode} /></ConfigProvider>);
};const ThemeWrapper: React.FC<{ isDarkMode: boolean; setIsDarkMode: React.Dispatch<React.SetStateAction<boolean>> }> = ({ isDarkMode, setIsDarkMode }) => {const { token } = theme.useToken(); // 確保 useToken 在 ConfigProvider 作用域內return (<Layout style={{minHeight : window.innerHeight}}><Headerstyle={{display: 'flex',alignItems: 'center',background: token.colorBgElevated, // 修正 Header 適配暗黑模式}}><Menutheme={isDarkMode ? 'dark' : 'light'}mode="horizontal"defaultSelectedKeys={['0']}items={items}style={{flex: 1,minWidth: 0,background: token.colorBgElevated, // 確保 Menu 顏色一致}}/><div><Switchchecked={!isDarkMode}onChange={() => setIsDarkMode(!isDarkMode)}checkedChildren="🌙"unCheckedChildren="??"/></div></Header><Content style={{ padding: '0 48px' }}><Breadcrumbstyle={{ margin: '16px 0' }}items={[{ title: 'Home' }, { title: 'List' }, { title: 'App' }]}/><divstyle={{background: token.colorBgContainer, // 確保背景顏色正確color: token.colorText, // 文字顏色適配暗黑模式minHeight: 580,padding: 24,borderRadius: token.borderRadiusLG,}}>Content</div></Content><Footer style={{ background: token.colorBgElevated, textAlign: 'center' }}>Ant Design ?{new Date().getFullYear()} Created by Ant UED</Footer></Layout>);
};export default App;
我遇到的BUG
問題代碼
import React, { useState } from 'react';
import { Breadcrumb, Layout, Menu, theme, ConfigProvider, Switch } from 'antd';
import './index.css';const { Header, Content, Footer } = Layout;const items = [{key: 0,label: '測試',},
];const App: React.FC = () => {// 主題切換狀態const [isDarkMode, setIsDarkMode] = useState(false);// 獲取當前主題 token(應該在組件頂層調用)const { token } = theme.useToken();return (<ConfigProvidertheme={{algorithm: isDarkMode ? theme.darkAlgorithm : theme.defaultAlgorithm,}}><Layout><Header style={{ display: 'flex', alignItems: 'center' }}><Menutheme={isDarkMode ? 'dark' : 'light'}mode="horizontal"defaultSelectedKeys={['0']}items={items}style={{ flex: 1, minWidth: 0 }}/><Switchchecked={!isDarkMode}onChange={() => setIsDarkMode(!isDarkMode)}checkedChildren="🌙"unCheckedChildren="??"/></Header><Content style={{ padding: '0 48px' }}><Breadcrumbstyle={{ margin: '16px 0' }}items={[{ title: 'Home' }, { title: 'List' }, { title: 'App' }]}/><divstyle={{backgroundColor: token.colorBgContainer,minHeight: 1080,padding: 24,borderRadius: token.borderRadiusLG,}}>Content</div></Content><Footer style={{ textAlign: 'center' }}>Ant Design ?{new Date().getFullYear()} Created by Ant UED</Footer></Layout></ConfigProvider>);
};export default App;
BUG1:暗黑模式下內容區不變成深色
效果如圖:
原因:theme.useToken() 的 token 在 ConfigProvider 重新渲染時沒有立即更新。
解決辦法:確保 theme.useToken() 在 ConfigProvider 作用域內,并且 ConfigProvider 重新渲染時 token 正確更新。
BUG2:光亮模式下的左右區域是深色
效果如下:
產生原因:Header 組件默認沒有使用 theme.useToken() 提供的背景色,而是繼承了 Ant Design 默認的 light 主題顏色
解決辦法:使用 token.colorBgElevated 作為 Header 的背景(它適用于暗黑模式的頂層容器)。確保 Header、Menu、Switch 共享相同的 backgroundColor。
補充知識
ConfigProvider是什么?
ConfigProvider 是 Ant Design 中的一個組件,用于在應用中全局配置和定制 Ant Design 組件的默認行為和主題。它是一個上下文提供器,用來設置應用中的全局配置,比如主題、國際化語言、組件的默認樣式等。
Ant Design中的theme如何使用?
在 Ant Design 中,theme 是用于設置和管理 UI 樣式的工具,通常與 ConfigProvider 一起使用來定制整個應用的視覺風格。theme 允許開發者通過配置顏色、字體、布局、組件樣式等來調整 Ant Design 組件的外觀,使其與應用的整體設計保持一致。
theme 配置的常見字段
- colorPrimary:設置主色調。影響許多組件的顏色,如按鈕、鏈接、選中狀態等。
- colorLink:設置鏈接文字的顏色。
- colorBgBase:設置基礎背景顏色。
- colorTextBase:設置基礎文字顏色。
- borderRadiusBase:設置全局組件的邊框圓角。
- fontSizeBase:設置基礎字體大小。
- size:設置默認組件尺寸(如 small, middle, large)。
主題算法
Ant Design 支持多種主題算法,其中常見的包括:
- theme.defaultAlgorithm:默認主題算法,通常用于淺色模式。
- theme.darkAlgorithm:暗黑主題算法,用于暗黑模式。
通過 useToken 獲取主題
在使用主題時,你可以通過 theme.useToken 來訪問當前的主題 token 和樣式變量。例如,訪問當前主題下的背景色、文本色等:
import React from 'react';
import { theme } from 'antd';const App: React.FC = () => {const { token } = theme.useToken();return (<div style={{ backgroundColor: token.colorBgContainer, color: token.colorText }}>Content with dynamic theme</div>);
};export default App;