> 웹 프론트엔드 > 프런트엔드 Q&A > Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

青灯夜游
풀어 주다: 2021-12-20 14:19:37
앞으로
3461명이 탐색했습니다.

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 이 기사는 Ant Design에서 테마를 사용자 정의하고 동적 테마를 구현하는 방법을 소개합니다. 모든 사람에게 도움이 되기를 바랍니다.

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

1. 머리말

안녕하세요 여러분 오랜만이군요. 최근 프로젝트에서 동적 테마가 필요하다고 느껴서 구현 과정을 기록해 두겠습니다. 이 글은 조금 길 수 있으니 인내심을 갖고 읽어주세요

2. 환경 준비

편의상 이 글의 예시에서는 create-react-app + caco + craco-less를 사용하여 구현합니다. create-react-app + caco + craco-less 实现:

# 创建项目
create-react-app demo
# 安装必要依赖
yarn add antd # 记得要装最新版
yarn add -D @craco/craco craco-less babel-plugin-import
로그인 후 복사

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

{
  scripts: {
    "start": "craco start"
  }
}
로그인 후 복사

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

const CracoLessPlugin = require('craco-less');

module.exports = {
  plugins: [{ plugin: CracoLessPlugin }],
};
로그인 후 복사

然后,改一下 App.js

import { useState } from 'react';
import { Avatar, Card, Button, Space, Switch } from 'antd';

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

  const handleThemeChange = (checked) => {
    setTheme(checked ? 'light' : 'dark');
  };

  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;
로그인 후 복사

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

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

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

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

三、如何引入主题?

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

1. 引入样式文件

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

// App.js
import &#39;antd/dist/antd.css&#39;;
로그인 후 복사

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

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

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

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

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
로그인 후 복사

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

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

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

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

@import &#39;~antd/dist/antd.less&#39;;
로그인 후 복사

2. babel-plugin-import

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

// craco.config.js

module.exports = {
  babel: {
    plugins: [
      [&#39;import&#39;, { libraryName: &#39;antd&#39;, libraryDirectory: &#39;es&#39;, style: true }],
    ],
  },
  // ...
};
로그인 후 복사

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

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

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

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

├── 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
로그인 후 복사

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

const darkThemeSingle = {
  "theme": "dark",
  "popover-background": "#1f1f1f",
  "popover-customize-border-color": "#3a3a3a",
  "body-background": "@black",
  "component-background": "#141414",
  // ...
};
로그인 후 복사

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

1. 定制主题

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

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

@primary-color: green;
로그인 후 복사

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

// 2. 通过 lessOptions
// craco.config.js
module.exports = {
  // ...
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {
              &#39;primary-color&#39;: &#39;cyan&#39;,
            },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
로그인 후 복사

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

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


Less 小课堂

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

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

# 转义 less 文件
npx lessc ./src/App.less ./src/App.css --js
로그인 후 복사

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

.ant-btn-primary {
  border-color: green;
  background: green;
}
로그인 후 복사
로그인 후 복사

는 < code>package.json에서 npm-script를 수정합니다. 🎜
npx lessc ./src/App.less ./src/App.css --js --modify-var="primary-color: cyan"
로그인 후 복사
로그인 후 복사
🎜그런데 초기 craco.config.js</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;">.ant-btn-primary { border-color: cyan; background: cyan; }</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div>🎜 그런 다음 <code>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; }
}
로그인 후 복사
로그인 후 복사
🎜그런 다음 시작하면 다음 인터페이스가 표시됩니다. 🎜🎜Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.🎜
🎜스타일이 없는 이유는 이전 글을 읽어보시면 됩니다"Vite가 당신을 만족시킬 수 있나요?" 》🎜🎜https://mp.weixin.qq.com/s/68E7CBXrhAd4u5kAt99nOA🎜

3. 테마 소개? 🎜🎜Ant Design에는 테마를 소개하는 자세가 많이 있는데, 아래에서 간단히 정리해 보겠습니다. 🎜🎜1. 스타일 파일 소개🎜🎜 App.js에서 직접 스타일 파일 소개: 🎜
var parseTree = new ParseTree(root, imports);
로그인 후 복사
로그인 후 복사
🎜근데 craco-less를 사용하기 때문에 Ant Designless 파일을 사용하지만, antd를 직접 import하는 경우에는 . less를 사용하면 다음 오류가 발생합니다: 🎜🎜Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.🎜🎜이 문제를 해결하는 것은 매우 간단합니다. lessOption에서 javascriptEnabled를 켜면 됩니다. 🎜
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;
  	}
  },
  // ...
]
로그인 후 복사
로그인 후 복사
🎜그러면 다음을 볼 수 있습니다. 다음 인터페이스: 🎜🎜Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다. 🎜🎜【관련 추천: "Ant Design Pro 애플리케이션"]🎜🎜물론이죠. App.less에 도입하도록 선택할 수도 있습니다: 🎜
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;
}
로그인 후 복사
로그인 후 복사
🎜babel-plugin-import< /strong> 🎜🎜이전 글에서 babel-plugin-import를 사용하는 방법에 대해 이야기했는데, craco와 함께 사용하는 단계는 동일하지만 필요합니다. craco.config.js를 사용하려면 해당 구성을 추가하기만 하면 됩니다: 🎜
// craco.config.js
module.exports = {
  // ...
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {
              ...getThemeVariables({
                dark: true,
              }),
            },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
로그인 후 복사
로그인 후 복사
🎜이 방법으로 App.js/App.less에서 위에 소개된 스타일을 삭제할 수 있습니다. 🎜

4. 맞춤 테마와 동적 테마를 구현하는 방법은 무엇인가요? 🎜🎜위의 두 가지 방법은 Ant Design 스타일을 도입하는 데 가장 일반적으로 사용되는 방법입니다. 위의 방법을 기반으로 원본 스타일을 수정하고 덮어쓰는 방법은 다음과 같습니다. 🎜🎜실제로 antd/dist에 제공되는 스타일 파일이 많이 있는 것을 확인할 수 있습니다: 🎜
// App.less
@import &#39;antd/dist/antd.variable.less&#39;;
로그인 후 복사
로그인 후 복사
🎜antd.(dark|compact).less 두 파일은 어둡고 컴팩트 모드 스타일이며 antd.variable.less 파일은 최신 버전의 Ant Design에서만 사용할 수 있는 파일입니다. .less 스타일 파일 외에도 여러 xxx-theme.js 파일이 있다는 것을 알 수 있습니다. dark-theme.js로 시작하는 각 테마의 변수 값 예: 🎜
// App.js
// 增加下面一行
ConfigProvider.config({ theme: { primaryColor: &#39;aquamarine&#39; } });
로그인 후 복사
로그인 후 복사
🎜사용 방법은 아래에서 설명하겠습니다. 이제 이 글의 주제인 맞춤형 구현을 시작하겠습니다. 테마와 동적 테마. 🎜🎜1. 테마 사용자 정의🎜🎜사용자 정의 테마를 구현하려면 다음과 같이 매우 간단합니다< em> 스타일 재정의예를 들어 다크 테마를 사용할 때 다크 모드 스타일 파일이 직접 도입됩니다. 예를 들어 기본 테마에서 기본 색상을 수정하려는 경우 일반적으로 수정하는 두 가지 방법이 있습니다. 스타일 파일이나 lessOption을 통해. 🎜
// App.js
ConfigProvider.config({
  theme: {
    primaryColor: checked ? &#39;aquamarine&#39; : &#39;darkgreen&#39;,
  },
});
로그인 후 복사
로그인 후 복사
🎜Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.🎜
// node_modules/antd/es/config-provider/context.d.ts
interface Theme {
    primaryColor?: string;
    infoColor?: string;
    successColor?: string;
    processingColor?: string;
    errorColor?: string;
    warningColor?: string;
}
로그인 후 복사
로그인 후 복사
🎜🎜🎜필요 이제 이 두 가지 테마 커스터마이징 방법을 동시에 사용하면 두 번째 방법으로 modifyVars를 통해 설정한 내용만 적용됩니다. 왜냐고 물으시면 less🎜
🎜Less small class🎜
🎜Prerequisite: in Introduce 로 설명하는 추가 강의를 삽입하겠습니다. >antd.lessApp.less로 바꾸고 @primary-color를 덮어씁니다(위에서 구성한 녹색을 예로 사용)🎜
🎜less터미널 명령을 통해 .less 파일을 CSS로 이스케이프할 수 있는 명령줄을 제공합니다. </ 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">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div>🎜 <code>App.css에 있는 primary-color가 무엇인지 살펴보겠습니다. 🎜
.ant-btn-primary {
  border-color: green;
  background: green;
}
로그인 후 복사
로그인 후 복사

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

npx lessc ./src/App.less ./src/App.css --js --modify-var="primary-color: cyan"
로그인 후 복사
로그인 후 복사

在看下生成的 App.css 嘞:

.ant-btn-primary {
  border-color: cyan;
  background: cyan;
}
로그인 후 복사
로그인 후 복사

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; }
}
로그인 후 복사
로그인 후 복사

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

var parseTree = new ParseTree(root, imports);
로그인 후 복사
로그인 후 복사

这一步是将 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;
  	}
  },
  // ...
]
로그인 후 복사
로그인 후 복사

这样是不是可以理解了?就是 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;
}
로그인 후 복사
로그인 후 복사

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

// craco.config.js
module.exports = {
  // ...
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {
              ...getThemeVariables({
                dark: true,
              }),
            },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
로그인 후 복사
로그인 후 복사

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

就是这么简单,在使用 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;;
로그인 후 복사
로그인 후 복사

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

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

// App.js
// 增加下面一行
ConfigProvider.config({ theme: { primaryColor: &#39;aquamarine&#39; } });
로그인 후 복사
로그인 후 복사

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

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

// App.js
ConfigProvider.config({
  theme: {
    primaryColor: checked ? &#39;aquamarine&#39; : &#39;darkgreen&#39;,
  },
});
로그인 후 복사
로그인 후 복사

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

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

// node_modules/antd/es/config-provider/context.d.ts
interface Theme {
    primaryColor?: string;
    infoColor?: string;
    successColor?: string;
    processingColor?: string;
    errorColor?: string;
    warningColor?: string;
}
로그인 후 복사
로그인 후 복사

可以看到,通过这种方式来配置的颜色仅有上面六种,但如果你想 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;);
로그인 후 복사
로그인 후 복사

所以他只是对这几种颜色进行了特定处理,而对于其它的颜色(比如组件背景色)等并未作处理,但即使某些颜色的命名方式也符合这种规范,也不会奏效,毕竟 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);
	// ...
}
로그인 후 복사

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

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

1Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

具体内容可以看上面截图,我就不再赘述,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;;
  }
}
로그인 후 복사

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

Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.

如何实现修改 :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]);
  });
};
로그인 후 복사

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;
  // ...
},
로그인 후 복사

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

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

위 내용은 Ant Design에서 동적 테마를 사용자 정의하는 방법은 무엇입니까? 구현 방법에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿