Heim > Web-Frontend > Front-End-Fragen und Antworten > Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

青灯夜游
Freigeben: 2021-12-20 14:19:37
nach vorne
3461 Leute haben es durchsucht

Wie kann ich dynamische Themen in Ant Design anpassen? In diesem Artikel wird erläutert, wie Sie Themen anpassen und dynamische Themen in Ant Design implementieren. Ich hoffe, er ist für alle hilfreich!

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

1. Vorwort

Hallo zusammen, ich habe vor Kurzem die Notwendigkeit dynamischer Themen im Projekt festgestellt, daher werde ich den Implementierungsprozess aufzeichnen. Dieser Artikel ist möglicherweise etwas lang. Bitte lesen Sie ihn geduldig.

# 创建项目
create-react-app demo
# 安装必要依赖
yarn add antd # 记得要装最新版
yarn add -D @craco/craco craco-less babel-plugin-import
Nach dem Login kopieren

wird < einfach das npm-script in code>package.json ändern:

{
  scripts: {
    "start": "craco start"
  }
}
Nach dem Login kopieren

Übrigens, fügen Sie den anfänglichen craco.config.js</code hinzu >: <code>create-react-app + caco + craco-less 实现:

const CracoLessPlugin = require(&#39;craco-less&#39;);

module.exports = {
  plugins: [{ plugin: CracoLessPlugin }],
};
Nach dem Login kopieren

package.json 中的 npm-script 修改一下即可:

import { useState } from &#39;react&#39;;
import { Avatar, Card, Button, Space, Switch } from &#39;antd&#39;;

function App() {
  const [theme, setTheme] = useState(&#39;light&#39;);
  const checked = theme === &#39;light&#39;;

  const handleThemeChange = (checked) => {
    setTheme(checked ? &#39;light&#39; : &#39;dark&#39;);
  };

  return (
    <div className="App">
      <Card title={<Avatar size="large" src={logo} />}>
        <Space>
          <Switch
            checked={checked}
            checkedChildren="亮"
            unCheckedChildren="暗"
            onChange={handleThemeChange}
          />
          <Button type="primary">动态主题</Button>
        </Space>
      </Card>
    </div>
  );
}

export default App;
Nach dem Login kopieren

顺便添加下初始的 craco.config.js

// App.js
import &#39;antd/dist/antd.css&#39;;
Nach dem Login kopieren

然后,改一下 App.js

const CracoLessPlugin = require(&#39;craco-less&#39;);

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
Nach dem Login kopieren

然后启动就可以看到如下界面:

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

至于为何没有样式,各位可以看之前的文章 《Vite 能满足你吗?》

https://mp.weixin.qq.com/s/68E7CBXrhAd4u5kAt99nOA

三、如何引入主题?

Ant Design 中,有很多种姿势引入主题,下面先来简单的整理一下。

1. 引入样式文件

直接在 App.js 中引入样式文件:

@import &#39;~antd/dist/antd.less&#39;;
Nach dem Login kopieren

但既然使用了 craco-less 那就使用 Ant Designless 文件吧,但是当你直接引入 antd.less 时,会得到如下错误:

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

解决这个问题很简单,只需要在 lessOption 中将 javascriptEnabled 打开即可:

// craco.config.js

module.exports = {
  babel: {
    plugins: [
      [&#39;import&#39;, { libraryName: &#39;antd&#39;, libraryDirectory: &#39;es&#39;, style: true }],
    ],
  },
  // ...
};
Nach dem Login kopieren

然后就可以看到如下界面:

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

【相关推荐:《Ant Design Pro应用》】

当然你也可以选择在 App.less 中引入:

├── antd.compact.less
├── antd.dark.less
├── antd.less
├── antd.variable.less
├── compact-theme.js
├── dark-theme.js
├── default-theme.js
├── theme.js
└── variable-theme.js
Nach dem Login kopieren

2. babel-plugin-import

之前的文章中说过如何使用 babel-plugin-import,配合 craco 的使用步骤是一样的,只不过需要在 craco.config.js 中添加对应的配置即可:

const darkThemeSingle = {
  "theme": "dark",
  "popover-background": "#1f1f1f",
  "popover-customize-border-color": "#3a3a3a",
  "body-background": "@black",
  "component-background": "#141414",
  // ...
};
Nach dem Login kopieren

这样就可以删掉上面在 App.js/App.less 引入的样式了。

四、如何实现定制主题和动态主题?

上面两种方式就是最常用的引入 Ant Design 样式的方式,下面讲基于上面的方式来讲解如何修改覆盖原有样式。

其实可以发现在 antd/dist 中提供了很多种样式文件:

// 1. 通过修改样式文件
// App.less
@import  &#39;~antd/dist/antd.less&#39;;

@primary-color: green;
Nach dem Login kopieren

antd.(dark|compact).less 两个文件分别是黑暗和紧凑模式的样式,而 antd.variable.less 文件则是最新版 Ant Design 才有的文件,它有什么用下面会说到,除了 .less 样式文件之外各位会发现还有几个 xxx-theme.js 文件,如果你打开会发现里面其实都是各个主题的变量值,以 dark-theme.js 为例:

// 2. 通过 lessOptions
// craco.config.js
module.exports = {
  // ...
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {
              &#39;primary-color&#39;: &#39;cyan&#39;,
            },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
Nach dem Login kopieren

如何使用下面会讲,现在就开始本文的主题:实现定制主题和动态主题。

1. 定制主题

如果你想实现定制主题,那很简单,简单来说就是 样式覆盖,比如使用黑暗主题就直接引入黑暗模式的样式文件,比如在默认主题下想修改主色调一般有两种方式:通过修改样式文件或通过 lessOption

# 转义 less 文件
npx lessc ./src/App.less ./src/App.css --js
Nach dem Login kopieren

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

.ant-btn-primary {
  border-color: green;
  background: green;
}
Nach dem Login kopieren
Nach dem Login kopieren

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

需要说一下,如果同时使用了这两种定制主题的方式,则只会应用第二种通过 modifyVars 设置的内容。如果你问我为啥,那我就额外插一节 less 讲解的课吧


Less 小课堂

前提:在 App.less 中引入 antd.less 并且覆盖 @primary-color(以上面配置的 green 为例)

less 提供了命令行让我们可以通过 Terminal 命令将 .less 文件转义为 CSS

npx lessc ./src/App.less ./src/App.css --js --modify-var="primary-color: cyan"
Nach dem Login kopieren
Nach dem Login kopieren

让我们看一下 App.css 中的 primary-color

.ant-btn-primary {
  border-color: cyan;
  background: cyan;
}
Nach dem Login kopieren
Nach dem Login kopieren

Dann ändern Sie App.js: 🎜
# data
@import &#39;antd/dist/antd.less&#39;;

@primary-color: green;

.App {
  text-align: center;
}

# options
{
  javascriptEnabled: true,
  modifyVars: { &#39;primary-color&#39;: &#39;cyan&#39; }
}
Nach dem Login kopieren
Nach dem Login kopieren
🎜Dann starten Sie und Sie sehen die folgende Oberfläche: 🎜🎜Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen🎜
🎜Warum es keinen Stil gibt, können Sie im vorherigen Artikel lesen „Kann Vite Sie zufriedenstellen?“ 》🎜🎜https://mp.weixin.qq.com/s/68E7CBXrhAd4u5kAt99nOA🎜

3 Thema vorstellen? 🎜🎜In Ant Design gibt es viele Haltungen zur Einführung in Themen. 🎜🎜1. Stildateien einführen🎜🎜Stildateien direkt in App.js einführen: 🎜
var parseTree = new ParseTree(root, imports);
Nach dem Login kopieren
Nach dem Login kopieren
🎜Aber da Sie craco-less verwenden, dann verwenden Sie die less-Datei von Ant Design, aber wenn Sie antd direkt importieren. weniger, erhalten Sie die folgende Fehlermeldung: 🎜🎜Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen🎜🎜Die Lösung dieses Problems ist sehr einfach. Aktivieren Sie einfach javascriptEnabled in lessOption: 🎜
console.log(parseTree.root.rules);
// Rules AST
[
  // ...
  Node {
  	name: &#39;@primary-color&#39;,
  	value: Node {
  		value: &#39;green&#39;
  	}
  },
  Node {
  	name: &#39;@primary-color&#39;,
  	value: Node {
  		value: &#39;cyan&#39;
  	}
  },
  // ...
]
Nach dem Login kopieren
Nach dem Login kopieren
🎜Dann sehen Sie Gehe zu Folgende Schnittstelle: 🎜🎜Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen 🎜🎜【Verwandte Empfehlung: „Ant Design Pro-Anwendung"]🎜🎜Natürlich tun Sie das Sie können es auch in App.less einführen: 🎜
function getThemeVariables(options = {}) {
  let themeVar = {
    &#39;hack&#39;: `true;@import "${require.resolve(&#39;antd/lib/style/color/colorPalette.less&#39;)}";`,
    ...defaultTheme
  };
  if(options.dark) {
    themeVar = {
      ...themeVar,
      ...darkThemeSingle
    }
  }
  if(options.compact){
    themeVar = {
      ...themeVar,
      ...compactThemeSingle
    }
  }
  return themeVar;
}
Nach dem Login kopieren
Nach dem Login kopieren
🎜2 /strong> 🎜🎜Im vorherigen Artikel habe ich darüber gesprochen, wie man babel-plugin-import verwendet. Die Schritte zur Verwendung mit craco sind die gleichen, aber Sie benötigen Um craco.config.js zu verwenden, fügen Sie einfach die entsprechende Konfiguration hinzu: 🎜
// craco.config.js
module.exports = {
  // ...
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {
              ...getThemeVariables({
                dark: true,
              }),
            },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
Nach dem Login kopieren
Nach dem Login kopieren
🎜Auf diese Weise können Sie die oben in App.js/App.less eingeführten Stile löschen. 🎜

4. Wie implementiert man benutzerdefinierte Themes und dynamische Themes? 🎜🎜Die beiden oben genannten Methoden sind die am häufigsten verwendeten Methoden zur Einführung von Ant Design-Stilen. Basierend auf den oben genannten Methoden wird im Folgenden erläutert, wie die ursprünglichen Stile geändert und überschrieben werden. 🎜🎜Tatsächlich können Sie feststellen, dass in antd/dist viele Stildateien bereitgestellt werden: 🎜
// App.less
@import &#39;antd/dist/antd.variable.less&#39;;
Nach dem Login kopieren
Nach dem Login kopieren
🎜antd.(dark|compact).less Die beiden Dateien sind Dunkel- und Kompaktmodus-Stil, und die Datei antd.variable.less ist eine Datei, die nur in der neuesten Version von Ant Design verfügbar ist. Ihre Verwendung wird unten erläutert, mit Ausnahme von Zusätzlich zu den .less-Dateien werden Sie feststellen, dass es mehrere xxx-theme.js-Dateien gibt. Wenn Sie sie öffnen, werden Sie feststellen, dass es sich tatsächlich um die Dateien handelt Variablenwerte jedes Themes, beginnend mit dark-theme.js Zum Beispiel: 🎜
// App.js
// 增加下面一行
ConfigProvider.config({ theme: { primaryColor: &#39;aquamarine&#39; } });
Nach dem Login kopieren
Nach dem Login kopieren
🎜Wie man es verwendet, wird unten besprochen. Beginnen wir nun mit dem Thema dieses Artikels: Implementierung benutzerdefinierter Themes und dynamische Themen. 🎜🎜1 Passen Sie das Theme an🎜🎜Wenn Sie ein individuelles Theme implementieren möchten, ist es ganz einfach, sagen Sie einfach < em> Stilüberschreibung Wenn Sie beispielsweise ein dunkles Thema verwenden, wird die Stildatei für den dunklen Modus direkt eingeführt. Wenn Sie beispielsweise die Hauptfarbe unter dem Standardthema ändern möchten, gibt es im Allgemeinen zwei Möglichkeiten: durch Ändern die Style-Datei oder über lessOption. 🎜
// App.js
ConfigProvider.config({
  theme: {
    primaryColor: checked ? &#39;aquamarine&#39; : &#39;darkgreen&#39;,
  },
});
Nach dem Login kopieren
Nach dem Login kopieren
🎜Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen🎜
// node_modules/antd/es/config-provider/context.d.ts
interface Theme {
    primaryColor?: string;
    infoColor?: string;
    successColor?: string;
    processingColor?: string;
    errorColor?: string;
    warningColor?: string;
}
Nach dem Login kopieren
Nach dem Login kopieren
🎜Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen🎜🎜Muss Wenn nun diese beiden Methoden zum Anpassen des Themas gleichzeitig verwendet werden, wird nur der Inhalt angewendet, der von der zweiten über modifyVars festgelegt wurde. Wenn Sie mich fragen, warum, dann werde ich eine zusätzliche Lektion einfügen, die durch less🎜
🎜Less small class🎜
🎜Voraussetzung: in antd.less in App.less umwandeln und @primary-color überschreiben (nehmen Sie das oben konfigurierte grün als Beispiel)🎜
🎜less bietet eine Befehlszeile, die es uns ermöglicht, .less-Dateien über den Terminal-Befehl in CSS zu maskieren</ code>: 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">/** * @param {string} colorVal * @param {string} type */ var fillColor = function fillColor(colorVal, type) { var baseColor = new TinyColor(colorVal); var colorPalettes = generate(baseColor.toRgbString()); variables[&quot;&quot;.concat(type, &quot;-color&quot;)] = formatColor(baseColor); variables[&quot;&quot;.concat(type, &quot;-color-disabled&quot;)] = colorPalettes[1]; variables[&quot;&quot;.concat(type, &quot;-color-hover&quot;)] = colorPalettes[4]; variables[&quot;&quot;.concat(type, &quot;-color-active&quot;)] = colorPalettes[7]; variables[&quot;&quot;.concat(type, &quot;-color-outline&quot;)] = baseColor.clone().setAlpha(0.2).toRgbString(); variables[&quot;&quot;.concat(type, &quot;-color-deprecated-bg&quot;)] = colorPalettes[1]; variables[&quot;&quot;.concat(type, &quot;-color-deprecated-border&quot;)] = colorPalettes[3]; }; // 使用如下 fillColor(theme.successColor, &amp;#39;success&amp;#39;);</pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</div></div>🎜Lassen Sie uns einen Blick darauf werfen, was <code>primary-color in App.css ist: 🎜
.ant-btn-primary {
  border-color: green;
  background: green;
}
Nach dem Login kopieren
Nach dem Login kopieren

可以看到 primary-color 设为 green 生效了,我们再加上 modifyVars 看下呢?

npx lessc ./src/App.less ./src/App.css --js --modify-var="primary-color: cyan"
Nach dem Login kopieren
Nach dem Login kopieren

在看下生成的 App.css 嘞:

.ant-btn-primary {
  border-color: cyan;
  background: cyan;
}
Nach dem Login kopieren
Nach dem Login kopieren

Wow~竟然和我们本地开发时一样替换成了 modifyVars 中的内容!这又是为啥呢?

我们进入 node_modules/.bin/lessc 文件,在 parseLessFileconsole 一下 dataoptions 内容会得到源文件字符串和命令行中的一些配置,在此我们会得到:

# data
@import &#39;antd/dist/antd.less&#39;;

@primary-color: green;

.App {
  text-align: center;
}

# options
{
  javascriptEnabled: true,
  modifyVars: { &#39;primary-color&#39;: &#39;cyan&#39; }
}
Nach dem Login kopieren
Nach dem Login kopieren

随后我们再进入 node_modules/less/lib/less/render.js 文件,进入 render 方法可以看到:

var parseTree = new ParseTree(root, imports);
Nach dem Login kopieren
Nach dem Login kopieren

这一步是将 less 转为 AST,让我们来看一下转换后的 AST

console.log(parseTree.root.rules);
// Rules AST
[
  // ...
  Node {
  	name: &#39;@primary-color&#39;,
  	value: Node {
  		value: &#39;green&#39;
  	}
  },
  Node {
  	name: &#39;@primary-color&#39;,
  	value: Node {
  		value: &#39;cyan&#39;
  	}
  },
  // ...
]
Nach dem Login kopieren
Nach dem Login kopieren

这样是不是可以理解了?就是 modifyVars 中的变量覆盖了样式文件中的变量。下课!


再回到定制主题的相关内容,现在说下如何使用上面说到的 darkSingleTheme,我们可以看下 theme.js 的内容:

function getThemeVariables(options = {}) {
  let themeVar = {
    &#39;hack&#39;: `true;@import "${require.resolve(&#39;antd/lib/style/color/colorPalette.less&#39;)}";`,
    ...defaultTheme
  };
  if(options.dark) {
    themeVar = {
      ...themeVar,
      ...darkThemeSingle
    }
  }
  if(options.compact){
    themeVar = {
      ...themeVar,
      ...compactThemeSingle
    }
  }
  return themeVar;
}
Nach dem Login kopieren
Nach dem Login kopieren

可以看到,如果我们在使用 getThemeVariables 时将 darkcompact 设为 true 就能应用上对应的样式,我们来试下:

// craco.config.js
module.exports = {
  // ...
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {
              ...getThemeVariables({
                dark: true,
              }),
            },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
Nach dem Login kopieren
Nach dem Login kopieren

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

就是这么简单,在使用 getThemeVariables 时也可以搭配前面所说的 modifyVars 来覆盖样式。这就是常用的定制主题的方式,就是之前所说的 覆盖变量,总结一下这两种方式:

  • 引入主题样式文件并覆盖对应 Less 变量;

  • 使用 getThemeVariables 引入对应主题,通过 modifyVars 覆盖变量值;

2. 动态主题

到现在 Ant Design 文档都没有出切换亮/暗模式的功能,但在文档中却有提到相应功能。在本文中主要介绍3种方式,其中一种就是官方出的 动态主题(实验性)

I. 动态切换样式文件

切换样式文件,这应该是最容易想到的一个方案,Ant Design 本来就提供了例如 default/dark/compact 主题的样式,我们只需要将这些文件保存在我们的项目中,按需切换即可,这个方案不赘述,实现起来也十分简单。

II. ConfigProvider

ConfigProviderAnt Design 提供的一个实验性的动态主题方案,使用很简单,在入口 .less 文件中引入 variable.less 文件,然后在 ConfigProvider 中复写对应变量,具体使用如下:

// App.less
@import &#39;antd/dist/antd.variable.less&#39;;
Nach dem Login kopieren
Nach dem Login kopieren

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

默认样式与 primary 一样,然后我们使用 ConfigProvider 修改主题色(还是以 primaryColor 为例):

// App.js
// 增加下面一行
ConfigProvider.config({ theme: { primaryColor: &#39;aquamarine&#39; } });
Nach dem Login kopieren
Nach dem Login kopieren

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

动态切换我们与上面使用方式一致:

// App.js
ConfigProvider.config({
  theme: {
    primaryColor: checked ? &#39;aquamarine&#39; : &#39;darkgreen&#39;,
  },
});
Nach dem Login kopieren
Nach dem Login kopieren

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

这么方便,这么好用,他有什么不足之处么?有,但只要你不介意其实问题不大。通过 ConfigProvider 可以配置的颜色很有限:

// node_modules/antd/es/config-provider/context.d.ts
interface Theme {
    primaryColor?: string;
    infoColor?: string;
    successColor?: string;
    processingColor?: string;
    errorColor?: string;
    warningColor?: string;
}
Nach dem Login kopieren
Nach dem Login kopieren

可以看到,通过这种方式来配置的颜色仅有上面六种,但如果你想 extends Theme 来添加其他字段,那不好意思,行不通,再来看下它是如何处理这几种颜色的:

/**
 * @param {string} colorVal
 * @param {string} type
 */
var fillColor = function fillColor(colorVal, type) {
  var baseColor = new TinyColor(colorVal);
  var colorPalettes = generate(baseColor.toRgbString());
  variables["".concat(type, "-color")] = formatColor(baseColor);
  variables["".concat(type, "-color-disabled")] = colorPalettes[1];
  variables["".concat(type, "-color-hover")] = colorPalettes[4];
  variables["".concat(type, "-color-active")] = colorPalettes[7];
  variables["".concat(type, "-color-outline")] = baseColor.clone().setAlpha(0.2).toRgbString();
  variables["".concat(type, "-color-deprecated-bg")] = colorPalettes[1];
  variables["".concat(type, "-color-deprecated-border")] = colorPalettes[3];
};

// 使用如下
fillColor(theme.successColor, &#39;success&#39;);
Nach dem Login kopieren
Nach dem Login kopieren

所以他只是对这几种颜色进行了特定处理,而对于其它的颜色(比如组件背景色)等并未作处理,但即使某些颜色的命名方式也符合这种规范,也不会奏效,毕竟 Ant Design 使用了 if (theme.successColor) 这种方式来条件修改这些颜色。

III. CSS Variables

我打算在这一部分来介绍 II. ConfigProviderantd.variable.less 的内容,因为这个方法与 Ant Design 提供的 ConfigProvider 本质上有些类似:通过 CSS Variables 来修改全局的颜色。我们打开对应文件来简单看下内容:

// node_modules/antd/lib/style/themes/variable.less

html {
  @base-primary: @blue-6;
  
  --@{ant-prefix}-primary-color: @base-primary;
  --@{ant-prefix}-primary-color-hover: color(~`colorPalette(&#39;@{base-primary}&#39;, 5) `);
  --@{ant-prefix}-primary-color-active: color(~`colorPalette(&#39;@{base-primary}&#39;, 7) `);
  --@{ant-prefix}-primary-color-outline: fade(@base-primary, @outline-fade);
	// ...
}
Nach dem Login kopieren

上面的代码中涉及了 less 中几个比较基本的语法:Variable InterpolationEscaping

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

1Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

具体内容可以看上面截图,我就不再赘述,Ant Design 就通过这种方式实现了动态主题,将 color 值设置为可变的 CSS Variables。既然 ConfigProvider 可变的 color 有限,那我们就自己来定义这些颜色吧~这种方式实现起来比较复杂,但是可自定义性就无限可能了

// App.less
:root {
  --main-color: green;
}

.ant-btn {
  &.ant-btn-primary {
    border-color: ~&#39;var(--main-color)&#39;;
    background: ~&#39;var(--main-color)&#39;;
  }
}
Nach dem Login kopieren

看一下通过这种方式实现的效果:

Wie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen

如何实现修改 :root 中的样式呢?具体 Ant Design 的实现各位可以看 node_modules/antd/es/config-provider/cssVariable.jsnode_modules/rc-util/es/Dom/dynamicCSS.js 两个文件,内容十分简单。我先写了一个简易版:

const dark = {
  &#39;--main-color&#39;: &#39;darkgray&#39;,
};

const light = {
  &#39;--main-color&#39;: &#39;green&#39;,
};

const themes = { dark, light };

const changeTheme = (theme) => {
  const nextTheme = themes[theme];
  Object.keys(nextTheme).forEach((key) => {
    document.documentElement.style.setProperty(key, nextTheme[key]);
  });
};
Nach dem Login kopieren

changeTheme 方法就是修改 :root 中样式的方法。

但为什么不直接在 App.less 中采用 @primary-color: ~&#39;var(--main-color)&#39; 的形式,非要重写组件样式呢?

如果你去看 Ant Design 中样式文件的源码你会发现其中用到了很多 function,比如 less 中的 fade 函数:

Set the absolute opacity of a color. Can be applied to colors whether they already have an opacity value or not.

来自 Less 官网:https://lesscss.org/functions/#color-operations-fade

如果我们采用刚才说的那种形式来修改 @primary-color 等样式,less 就会抛出异常:Argument cannot be evaluated to a color

// node_modules/less/lib/less/functions/color.js

// fade 方法
function fade (color, amount) {
  var hsl = toHSL(color);
  hsl.a = amount.value / 100;
  hsl.a = clamp(hsl.a);
  return hsla(color, hsl);
}

// toHSL 方法
function toHSL(color) {
    // 此处的 color.toHSL 函数是下面 color.js 中的 toHSL 函数
    if (color.toHSL) {
        return color.toHSL();
    }
    else {
        throw new Error(&#39;Argument cannot be evaluated to a color&#39;);
    }
}

// node_modules/less/lib/less/tree/color.js
function toHSL () {
  var r = this.rgb[0] / 255, g = this.rgb[1] / 255, b = this.rgb[2] / 255, a = this.alpha;
  // ...
},
Nach dem Login kopieren

这样就可以看出如果我们传给 fade 函数的不是一个准确的颜色值,在 color.js 中是获取不到 rgb[0] 等值的,所以在 less 编译过程中就会直接报错。

更多编程相关知识,请访问:编程视频!!

Das obige ist der detaillierte Inhalt vonWie kann ich dynamische Themen in Ant Design anpassen? Lassen Sie uns über Implementierungsmethoden sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:juejin.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage