亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Ant Design中怎么定制動態主題

發布時間:2021-12-20 14:34:37 來源:億速云 閱讀:191 作者:小新 欄目:web開發

小編給大家分享一下Ant Design中怎么定制動態主題,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

環境準備

為了方便,本文中示例使用了 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中怎么定制動態主題

如何引入主題?

Ant Design 中,有很多種姿勢引入主題,下面先來簡單的整理一下。

1. 引入樣式文件

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

// App.js
import 'antd/dist/antd.css';

但既然使用了 craco-less 那就使用 Ant Designless 文件吧,但是當你直接引入 antd.less 時,會得到如下錯誤:

Ant Design中怎么定制動態主題

解決這個問題很簡單,只需要在 lessOption 中將 javascriptEnabled 打開即可:

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

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

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

Ant Design中怎么定制動態主題

當然你也可以選擇在 App.less 中引入:

@import '~antd/dist/antd.less';

2. babel-plugin-import

之前的文章中說過如何使用 babel-plugin-import,配合 craco 的使用步驟是一樣的,只不過需要在 craco.config.js 中添加對應的配置即可:

// craco.config.js

module.exports = {
  babel: {
    plugins: [
      ['import', { libraryName: 'antd', libraryDirectory: 'es', 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  '~antd/dist/antd.less';

@primary-color: green;

Ant Design中怎么定制動態主題

// 2. 通過 lessOptions
// craco.config.js
module.exports = {
  // ...
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {
              'primary-color': 'cyan',
            },
            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;
}

可以看到 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 'antd/dist/antd.less';

@primary-color: green;

.App {
  text-align: center;
}

# options
{
  javascriptEnabled: true,
  modifyVars: { 'primary-color': 'cyan' }
}

隨后我們再進入 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: '@primary-color',
  	value: Node {
  		value: 'green'
  	}
  },
  Node {
  	name: '@primary-color',
  	value: Node {
  		value: 'cyan'
  	}
  },
  // ...
]

這樣是不是可以理解了?就是 modifyVars 中的變量覆蓋了樣式文件中的變量。下課!


再回到定制主題的相關內容,現在說下如何使用上面說到的 darkSingleTheme,我們可以看下 theme.js 的內容:

function getThemeVariables(options = {}) {
  let themeVar = {
    'hack': `true;@import "${require.resolve('antd/lib/style/color/colorPalette.less')}";`,
    ...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 'antd/dist/antd.variable.less';

Ant Design中怎么定制動態主題

默認樣式與 primary 一樣,然后我們使用 ConfigProvider 修改主題色(還是以 primaryColor 為例):

// App.js
// 增加下面一行
ConfigProvider.config({ theme: { primaryColor: 'aquamarine' } });

Ant Design中怎么定制動態主題

動態切換我們與上面使用方式一致:

// App.js
ConfigProvider.config({
  theme: {
    primaryColor: checked ? 'aquamarine' : 'darkgreen',
  },
});

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, 'success');

所以他只是對這幾種顏色進行了特定處理,而對于其它的顏色(比如組件背景色)等并未作處理,但即使某些顏色的命名方式也符合這種規范,也不會奏效,畢竟 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('@{base-primary}', 5) `);
  --@{ant-prefix}-primary-color-active: color(~`colorPalette('@{base-primary}', 7) `);
  --@{ant-prefix}-primary-color-outline: fade(@base-primary, @outline-fade);
	// ...
}

上面的代碼中涉及了 less 中幾個比較基本的語法:Variable InterpolationEscaping

Ant Design中怎么定制動態主題

Ant Design中怎么定制動態主題

具體內容可以看上面截圖,我就不再贅述,Ant Design 就通過這種方式實現了動態主題,將 color 值設置為可變的 CSS Variables。既然 ConfigProvider 可變的 color 有限,那我們就自己來定義這些顏色吧~這種方式實現起來比較復雜,但是可自定義性就無限可能了

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

.ant-btn {
  &.ant-btn-primary {
    border-color: ~'var(--main-color)';
    background: ~'var(--main-color)';
  }
}

看一下通過這種方式實現的效果:

Ant Design中怎么定制動態主題

如何實現修改 :root 中的樣式呢?具體 Ant Design 的實現各位可以看 node_modules/antd/es/config-provider/cssVariable.jsnode_modules/rc-util/es/Dom/dynamicCSS.js 兩個文件,內容十分簡單。我先寫了一個簡易版:

const dark = {
  '--main-color': 'darkgray',
};

const light = {
  '--main-color': 'green',
};

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('Argument cannot be evaluated to a color');
    }
}

// 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中怎么定制動態主題”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

清远市| 东阳市| 拉萨市| 咸丰县| 嘉义市| 赣榆县| 南靖县| 九台市| 同仁县| 郓城县| 满洲里市| 渭南市| 忻城县| 遂昌县| 托克逊县| 敦化市| 镇巴县| 闵行区| 炎陵县| 宁南县| 洛南县| 涿州市| 康平县| 宿迁市| 安吉县| 广德县| 临安市| 开鲁县| 威宁| 宁强县| 大新县| 富民县| 长宁县| 疏勒县| 大英县| 上高县| 永嘉县| 湾仔区| 县级市| 黑龙江省| 台江县|