React + Antd實現動態切換主題功能
React + Antd 實現動態切換主題功能
前言
最近去ant design官網查閱資料,發現ant design最新版本已經更新到了4.17.x
,於是比較粗略的看了一下最近幾個4.17.x
版本的更新日誌,發現4.17.0
版本更新了大量內容(點選檢視4.17.0版本更新日誌),在這其中比較吸引我注意點一點是實現了動態主題的功能。不過點看動態主題的文件,卻標明著是實驗性的功能,真是一個大寫的囧。。。
在4.17.0
之前的版本里,實現動態主題的方法比較麻煩(也可能是我孤陋寡聞),通常是通過修改less變數的方式實現的,我個人覺得還是比較繁瑣的。在4.17.0
注意事項
以下摘自官方文件的描述:
- 該功能通過動態修改 CSS Variable 實現,因而在 IE 中頁面將無法正常展示。請先確認你的使用者環境是否需要支援 IE。
- 該功能在 [email protected] 版本起支援。
實現原理
動態切換主題的功能是,通過ConfigProvider
全域性化配置,設定統一的樣式字首,具體ConfigProvider
相關文件可以看這裡:https://ant-design.gitee.io/components/config-provider-cn/#API。
舉個例子,antd按鈕控制元件,引數type
'primary'
後,實際渲染出來後,會新增上class="ant-btn ant-btn-primary"
的屬性,其中ant-btn-primary
樣式控制按鈕的背景色及邊框線顏色。如下圖:
ant-btn-primary樣式
對於類名
ant-btn
以及ant-btn-primary
,ant
實際上作為樣式的字首。而我們如果動態的將樣式類名中的字首統一替換成其他的字串,就實現了主題切換的效果。
具體實現
-
依據官方文件,通過
ConfigProfider
在頂層修改prefixCls
:import { ConfigProvider } from 'antd'; export
-
編譯less
由於步驟1中,通過ConfigProfider
將樣式類名字首調整為custom
,我們需要重新通過lessc命令,將antd的預設樣式less檔案,重新編譯生成一份css檔案。※注意:如果未安裝less,則需要安裝less:npm install -g less
lessc --modify-var="ant-prefix=custom" node_modules/antd/dist/antd.variable.less custom.css
如果單單按照官方文件中的操作執行上述命令,控制檯會報錯:
SyntaxError: Inline JavaScript is not enabled. Is it set in your options? in D:\workspace\workspace_for_java\SPB-LERN\web-react-ts\node_modules\antd\lib\style\color\bezierEasing.less on line 110, column 1: 109 // https://github.com/ant-design/ant-motion/issues/44 110 .bezierEasingMixin(); 111
因為預設lessc命令未開啟javascript功能,需要通過引數開啟javascript功能,參考連結:https://lesscss.org/usage/#less-options-enable-inline-javascript-deprecated-。將上述命令新增
--js
引數後執行即可:lessc --js --modify-var="ant-prefix=custom" node_modules/antd/dist/antd.variable.less custom.css
-
按照步驟2中的命令,會生成一個
custom.css
,由於檔案過於龐大,擷取幾段內容如下:html { --custom-primary-color: #1890ff; --custom-primary-color-hover: #40a9ff; --custom-primary-color-active: #096dd9; --custom-primary-color-outline: rgba(24, 144, 255, 0.2); --custom-primary-1: #e6f7ff; --custom-primary-2: #bae7ff; --custom-primary-3: #91d5ff; --custom-primary-4: #69c0ff; --custom-primary-5: #40a9ff; --custom-primary-6: #1890ff; --custom-primary-7: #096dd9; --custom-primary-color-deprecated-pure: ; --custom-primary-color-deprecated-l-35: #cbe6ff; --custom-primary-color-deprecated-l-20: #7ec1ff; --custom-primary-color-deprecated-t-20: #46a6ff; --custom-primary-color-deprecated-t-50: #8cc8ff; --custom-primary-color-deprecated-f-12: rgba(24, 144, 255, 0.12); --custom-primary-color-active-deprecated-f-30: rgba(230, 247, 255, 0.3); --custom-primary-color-active-deprecated-d-02: #dcf4ff; /* 以下內容略去 */
其中第二行中的
--custom-primary-color
即為primary的樣色,預設為antd預設的藍色,用於測試效果,我們可以將該改色修改為紅色:html { --custom-primary-color: #ff0000;/* 修改為紅色 */ --custom-primary-color-hover: #40a9ff;
-
index.js
檔案引入上述步驟中的custom.css
檔案。※注意:預設的antd樣式檔案antd/dist/antd.css
也需要引入。index.js
檔案完整程式碼如下:import React, { useState } from "react"; import ReactDOM from "react-dom"; import { Button, DatePicker, Radio, Space, version } from "antd"; import { ConfigProvider } from "antd"; import "antd/dist/antd.css"; // antd預設樣式檔案 import "./custom.css"; // 修改後的樣式檔案 import "./index.css"; const TestComponent = () => { const [prefix, setPrefix] = useState("ant"); const handlePrefixChange = (e) => { setPrefix(e.target.value); }; return ( // ConfigProvider修改prefixCls <ConfigProvider prefixCls={prefix}> <div className="App"> <h1> <Space> Change Theme: {/* radio動態修改prefix */} <Radio.Group onChange={handlePrefixChange} value={prefix}> <Radio value="ant">Ant Style</Radio> <Radio value="custom">Custom Style</Radio> </Radio.Group> </Space> </h1> <h1>antd version: {version}</h1> <DatePicker /> <Button type="primary" style={{ marginLeft: 8 }}> Primary Button </Button> </div> </ConfigProvider> ); }; ReactDOM.render(<TestComponent />, document.getElementById("root"));
最終效果
最終效果從上圖我們可以看到,radio單選框選擇ant style時,此時頁面渲染主題色為ant預設的藍色,而radio選擇custom style後,頁面渲染的主題色已經動態切換成我們修改後的紅色。通過瀏覽器除錯視窗,我們可以發現,按鈕的class類名字首為ant
,選擇custom style後,class類名字首切換為custom
。
修改後的樣式
寫在最後
自此我們動態切換主題的效果就大功告成。
參考連結:
https://blog.csdn.net/m0_58016522/article/details/121751043
https://ant-design.gitee.io/changelog-cn
https://ant-design.gitee.io/docs/react/customize-theme-variable-cn