赞
踩
最近有个需求,要给系统做个主题切换功能,网上关于主题的方案挺多,准备做一些调研,因为项目是react+antd的一个后台系统,开始从antd官方文档中开始着手,做下整理对比,最后选一个最佳的方案用于实践。
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标签,用新的css链接替换原来的样式,这种方案实现上没有难度,也没有兼容问题,需要新建一套完全一样的样式类名,然后替换其中的色值,缺点是工作量太大,尤其开发中的项目来说,扩展性比较差,后期更换样式类名,需要同步更改主题样式文件:
theme2
另外一个是用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 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。