react+antd 使用腳手架動態修改主題色


最近做了一個需求,后台管理系統添加一個可以動態修改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也變成了紅色!

修改less變量

現在可以在 react 組件里使用window.less.modifyVars方法來修改主題變量色了!

  • 如何在組件里的 less 文件使用 less 變量。

    還記得開始配置config/webpack.config.js文件嗎?在 less 正則匹配的 loader 里往后添加一個style-resources-loader配置即可

style-resources-loader

使用注意

如果在啟動項目后,在去動態修改src/assets/theme/var.less里的全局 less 變量或者在組件 less 文件中修改或者引入 less 全局變量,會出現熱更新不生效,還需重啟項目才能發生變化。

在打包模式里影響不大!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM