最近做了一個需求,後臺管理系統新增一個可以動態修改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-theme
- 2. 使用
npm run eject
彈射出webpack
等配置檔案
D:\ant-theme>npm run eject
- 3. 安裝
antd-theme-generator
依賴
D:\ant-theme>cnpm i antd-theme-generator -D
或者
D:\ant-theme>npm i antd-theme-generator -D
- 4. 在根目錄下新建檔案
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 rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<!-- 在body下插入此段程式碼,配合使用window.less.modifyVars -->
<body>
<link
rel="stylesheet/less"
type="text/css"
href="%PUBLIC_URL%/color.less"
/>
<script>
window.less = { async: false, env: "production" };
</script>
<script
type="text/javascript"
src="https://cdn.bootcss.com/less.js/2.7.3/less.min.js"
></script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></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; // 邊框色
- 8. 修改
package.json
檔案的啟動指令碼。
{
"scripts": {
"start": "node color && node scripts/start.js",
"build": "node color && node scripts/build.js"
}
}
- 9. 使用 npm 指令碼執行專案
D:\ant-theme>npm run start
執行成功開啟瀏覽器輸入 http://localhost:3000/ 即可。
開啟控制檯,控制檯輸入以下程式碼檢查是否修改生效!
window.less.modifyVars({
"@primary-color": "red",
});
如圖,匯入的 antd 的 button 元件背景色變成了紅色。自定義的 less 檔案引用的@primary-color
也變成了紅色!
現在可以在 react 元件裡使用window.less.modifyVars
方法來修改主題變數色了!
- 如何在元件裡的 less 檔案使用 less 變數。
還記得開始配置
config/webpack.config.js
檔案嗎?在 less 正則匹配的 loader 裡往後新增一個style-resources-loader
配置即可
使用注意
如果在啟動專案後,在去動態修改src/assets/theme/var.less
裡的全域性 less 變數或者在元件 less 檔案中修改或者引入 less 全域性變數,會出現熱更新不生效,還需重啟專案才能發生變化。
在打包模式裡影響不大!