最近做了一个需求,后台管理系统添加一个可以动态修改ant-design主题色。查询了大多数的文章,发现基本都是抄来抄去,而且文章记录的也一点也不详细。刚刚把这个功能做完了,顺便记录一下如何去修改主题色。主要使用到的包是antd-theme-generator。使用起来非常方便,而且在热更新时,不会出现 js 内存爆栈现象。
主题思想:主要使用 antd 的 less 变量,修改全局的 less 变量,完成样式的更新。以下是 less 等版本信息。
案例网址: https://azhengpersonalblog.top/react-ant-admin/
{ "antd": "^4.15.5", "antd-theme-generator": "^1.2.5", "babel-plugin-import": "^1.13.3", "less": "^4.1.1", "less-loader": "^5.0.0", "style-resources-loader": "^1.4.1" }1. 首先使用create-react-app脚手架来创建一个项目ant-theme。
D:>npx create-react-app ant-theme2. 使用npm run eject弹射出webpack等配置文件
D:\ant-theme>npm run eject3. 安装antd-theme-generator依赖
D:\ant-theme>cnpm i antd-theme-generator -D 或者 D:\ant-theme>npm i antd-theme-generator -D4. 在根目录下新建文件color.js,代码如下所示
const { generateTheme } = require("antd-theme-generator"); const path = require("path"); const options = { antDir: path.join(__dirname, "./node_modules/antd"), stylesDir: path.join(__dirname, "./src"), // all files with .less extension will be processed varFile: path.join(__dirname, "./src/assets/theme/var.less"), // default path is Ant Design default.less file themeVariables: [ "@primary-color", "@link-color", "@success-color", "@warning-color", "@error-color", "@layout-text", "@layout-background", "@heading-color", "@text-color", "@text-color-secondary", "@disabled-color", "@border-color-base", ], outputFilePath: path.join(__dirname, "./public/color.less"), }; generateTheme(options) .then((less) => { console.log("Theme generated successfully"); }) .catch((error) => { console.log("Error", error); });5. 修改public/index.html,代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link href="http://www.likecs.com/%PUBLIC_URL%/favicon.ico" /> <meta content="width=device-width, initial-scale=1" /> <meta content="#000000" /> <meta content="Web site created using create-react-app" /> <link href="http://www.likecs.com/%PUBLIC_URL%/logo192.png" /> <link href="http://www.likecs.com/%PUBLIC_URL%/manifest.json" /> <title>React App</title> </head> <!-- 在body下插入此段代码,配合使用window.less.modifyVars --> <body> <link type="text/css" href="http://www.likecs.com/%PUBLIC_URL%/color.less" /> <script> window.less = { async: false, env: "production" }; </script> <script type="text/javascript" src="http://cdn.bootcss.com/less.js/2.7.3/less.min.js" ></script> <noscript>You need to enable JavaScript to run this app.</noscript> <div></div> </body> </html>6. 修改config/webpack.config.js文件,新增rules项打包 less
const path = require("path") //............... // 找到css正则匹配 新增less匹配 const cssRegex = /\.css$/; const cssModuleRegex = /\.module\.css$/; const lessRegex = /\.(less)$/; const lessModuleRegex = /\.module\.(less)$/; //............... module.exports = function (webpackEnv) { return { //............ module: { rules: [ // ......... { oneOf: [ // ......... { test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, }), sideEffects: true, }, { test: cssModuleRegex, use: [ ...getStyleLoaders({ importLoaders: 1, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, modules: { getLocalIdent: getCSSModuleLocalIdent, }, }), ], }, // less 文件匹配 { test: lessRegex, exclude: lessModuleRegex, use: [ { loader: "css-loader", }, { loader: "less-loader", options: { javascriptEnabled: true, }, }, //全局引入公共的less 文件 需要安装 style-resources-loader 包 { loader: "style-resources-loader", options: { patterns: path.resolve( paths.appSrc, "assets/theme/var.less" }, }, ], sideEffects: true, }, { test: lessModuleRegex, use: [ { loader: "css-loader", }, { loader: "less-loader", options: { javascriptEnabled: true, }, }, ], }, ], }, ], }, }; };7. 新增src/assets/theme/var.less文件,在里面定义 less 全局变量达到控制主题色。
@primary-color: rgb(24, 144, 255); // 全局主色 @link-color: rgb(24, 144, 255); // 链接色 @success-color: rgb(82, 196, 26); // 成功色 @warning-color: rgb(250, 173, 20); // 警告色 @error-color: rgb(245, 34, 45); // 错误色 @layout-text: rgb(241, 240, 240); // 布局字体色 @layout-background: rgba(0, 0, 0, 0.85); // 布局背景色 @heading-color: rgba(0, 0, 0, 0.85); // 标题色 @text-color: rgba(0, 0, 0, 0.65); // 主文本色 @text-color-secondary: rgba(0, 0, 0, 0.45); // 次文本色 @disabled-color: rgba(0, 0, 0, 0.25); // 失效色 @border-color-base: #d9d9d9; // 边框色