前端主題切換方案 -react-antd-
本文作者爲 360 技術中臺數據平臺部的前端開發工程師
原文標題:前端主題切換方案
原文地址:https://juejin.cn/post/7117911005841063944
背景
最近有個需求,要給系統做個主題切換功能,網上關於主題的方案挺多,準備做一些調研,因爲項目是 react+antd 的一個後臺系統,開始從 antd 官方文檔中開始着手,做下整理對比,最後選一個最佳的方案用於實踐。
技術選型
less.modifyVars
antd 提供的一種主題切換方式,通過配置 webpack 的 less-loader,添加 modifyVars 對象,官方已經內置了一些主題變量,每次構建時更換對應色值即可實現主題切換。
// webpack.config.js
module.exports = {
rules: [{
test: /\.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader', // translates CSS into CommonJS
}, {
loader: 'less-loader', // compiles Less to CSS
+ options: {
+ lessOptions: { // 如果使用less-loader@5,請移除 lessOptions 這一級直接配置選項。
+ modifyVars: {
+ 'primary-color': '#1DA57A',
+ 'link-color': '#1DA57A',
+ 'border-radius-base': '2px',
+ },
+ javascriptEnabled: true,
+ },
+ },
}],
// ...other rules
}],
// ...other config
}
Link 標籤替換
插入一個新的 Link 標籤,用新的 css 鏈接替換原來的樣式,這種方案實現上沒有難度,也沒有兼容問題,需要新建一套完全一樣的樣式類名,然後替換其中的色值,缺點是工作量太大,尤其開發中的項目來說,擴展性比較差,後期更換樣式類名,需要同步更改主題樣式文件:
theme2
CSS Variable
另外一個是用 ConfigProvider,需要注意在 antd@4.17.0-alpha.0 版本起才支持,而且 webpack 中如果使用了 babel-plugin-import,需要將其去除。本質是通過 CSS Variable(css 變量)實現,將顏色賦值變量,最大的問題是——有兼容性問題,在 IE 瀏覽器中不支持。補充:antd 好像對 CSS Variable 做了兼容處理。
-- import 'antd/dist/antd.min.css';
++ import 'antd/dist/antd.variable.min.css';
調用部分:
import { ConfigProvider } from 'antd';
ConfigProvider.config({
theme: {
primaryColor: '#25b864',
},
});
css-vars-ponyfill
爲彌補 css variable 的不足,css-vars-ponyfill 做了一套兼容處理,原理大概是在 ie 等不支持 css var 的瀏覽器中將 var()中的變量值替換爲對應色值,在支持 css var 的瀏覽器中不做處理。另外是操作 dom,所以在 node 環境中無法使用。css-vars-ponyfill 主要暴露了一個 cssVar 方法,方法入參如下:
export interface CSSVarsPonyfillOptions {
rootElement?: Document|HTMLElement;
shadowDOM?: boolean;
include?: string;
exclude?: string;
variables?: {[key: string]: string}; // 顏色鍵值對
onlyLegacy?: boolean;
preserveStatic?: boolean;
preserveVars?: boolean;
silent?: boolean;
updateDOM?: boolean;
updateURLs?: boolean;
watch?: null|boolean;
onBeforeSend?(xhr: XMLHttpRequest, elm: HTMLLinkElement|HTMLStyleElement, url: string): void;
onError?(message: string, elm: HTMLLinkElement|HTMLStyleElement, xhr: XMLHttpRequest, url: string): void;
onWarning?(message: string): void;
onSuccess?(cssText: string, elm: HTMLLinkElement|HTMLStyleElement, url: string): void;
onComplete?(cssText: string, styleElms: HTMLStyleElement[], cssVariables: {[key: string]: string}, benchmark: number): void;
onFinally?(hasChanged: boolean, hasNativeSupport: boolean, benchmark: number): void;
}
主要的參數:variables:顏色鍵值對,切換主題即更換不同的 variables
技術對比
less.modifyVars 是靜態更改主題,適合定製化主題,構建完成之後不能再變;css 標籤的方法工作量太大,擴展性差;css variable 比較靈活,但有兼容問題,相對於 css 標籤方法,擴展性好點;css-vars-ponyfill 是 css variable 的優化版,解決了兼容問題,雖然會有服務端渲染的問題,如果項目是在瀏覽器 dom 環境下無傷大雅。
補充
做了一個簡單的 demo,分別用三種方式實現主題切換:css 標籤,css variable,css-vars-ponyfill。GitHub 地址:react-antd-theme
theme_link
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/PqCNaffGDXyflQkAaiQfVA