ホームページ  >  記事  >  ウェブフロントエンド  >  Ant Design で動的テーマをカスタマイズするにはどうすればよいですか?導入方法について話しましょう

Ant Design で動的テーマをカスタマイズするにはどうすればよいですか?導入方法について話しましょう

青灯夜游
青灯夜游転載
2021-12-20 14:16:373291ブラウズ

Ant Design で動的テーマをカスタマイズするにはどうすればよいですか?この記事では、Ant Design でテーマをカスタマイズし、動的テーマを実装する方法を紹介します。

Ant Design で動的テーマをカスタマイズするにはどうすればよいですか?導入方法について話しましょう

1. はじめに

皆さん、お久しぶりです。最近プロジェクトで動的テーマが必要になったので、その実装を記録します。プロセス。この記事は少し長いかもしれません。気長にお読みください。

2. 環境の準備

便宜上、この記事の例では create-react-app caco craco-less# を使用します。 ## 実装:

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

package.jsonnpm-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

3. テーマの導入方法は?

Ant Design
では、テーマを紹介する姿勢がたくさんありますが、以下に簡単に整理してみましょう。

1. スタイル ファイルの導入

スタイル ファイルを App.js に直接導入します:

// App.js
import &#39;antd/dist/antd.css&#39;;

ただし、

craco-less を使用するため、Ant Design

less ファイルを使用しますが、antd.less を直接インポートする場合 # この問題の解決は非常に簡単です。

lessOption

Ant Design で動的テーマをカスタマイズするにはどうすればよいですか?導入方法について話しましょうjavascriptEnabled

をオンにするだけです。次のことができます。

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

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
次のインターフェイスが表示されます:

[関連する推奨事項: "

Ant Design Pro アプリケーション

"]Ant Design で動的テーマをカスタマイズするにはどうすればよいですか?導入方法について話しましょう

もちろん、

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 で上で紹介したスタイルを削除できます。 4. カスタマイズされたテーマと動的テーマを実装するにはどうすればよいですか? Ant Design

スタイルを導入するには、上記の 2 つの方法が最も一般的ですが、以下では、上記の方法に基づいて元のスタイルを変更および上書きする方法について説明します。

実際、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 2 2 つのファイルはそれぞれダーク モード スタイルとコンパクト モード スタイルで、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. カスタマイズされたテーマ

カスタマイズされたテーマを実装したい場合、それは非常に簡単です。スタイル オーバーライド

たとえば、ダーク テーマを使用する場合は、ダーク モード スタイル ファイルを直接導入します。たとえば、デフォルト テーマのメイン カラーを変更したい場合は、通常 2 つの方法があります: スタイル ファイルを変更するまたは

lessOption

を通じて。

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

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

テーマをカスタマイズするこれら 2 つの方法を同時に使用する場合、2 番目の方法のみが使用されることに注意してください。 modifyVars 設定内容。理由を尋ねられたら、

less

Ant Design で動的テーマをカスタマイズするにはどうすればよいですか?導入方法について話しましょう

Ant Design で動的テーマをカスタマイズするにはどうすればよいですか?導入方法について話しましょう小規模クラス

前提条件によって説明された追加のレッスンを挿入します。 : App.less

antd.less
を導入し、

@primary-color を上書きします (例として上記で設定した green

を使用します)

less は、ターミナル コマンド CSS## を通じて .less ファイルを にエスケープできるコマンド ラインを提供します。 #:

# 转义 less 文件
npx lessc ./src/App.less ./src/App.css --js

App.cssprimary-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: ~'var(--main-color)' 的形式,非要重写组件样式呢?

如果你去看 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。