umi项目中动态改变antd的主题色

4,591 阅读3分钟

一、编译时改变主题色

在项目根目录的.umirc.tsconfig/config.tsconfig文件夹可在根目录中新建,用来代替.umirc.ts做一些基本配置)文件中theme字段进行主题配置。
theme可以配置为一个对象或文件路径:

"theme": {
  "primary-color": "#1DA57A",
},

或者 一个 js 文件然后在.umirc.tsconfig/config.ts使用:

"theme": "./theme.js",

以下是一些最常用的通用变量:

@primary-color: #1890ff; // 全局主色
@link-color: #1890ff; // 链接色
@success-color: #52c41a; // 成功色
@warning-color: #faad14; // 警告色
@error-color: #f5222d; // 错误色
@font-size-base: 14px; // 主字号
@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-radius-base: 2px; // 组件/浮层圆角
@border-color-base: #d9d9d9; // 边框色
@box-shadow-base: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
  0 9px 28px 8px rgba(0, 0, 0, 0.05); // 浮层阴影

二、运行时改变主题色

1.新建相关目录和文件

在根目录下,新建public目录,引入less.min.js,下载路径为:cdn.bootcss.com/less.js/2.5…,同时新建public/styles目录,再在styles目录下创建antd.theme.lesscomponents.less两个文件。

  • antd.theme.less:用来放置覆盖 antd UI 组件库样式;
  • components.less:引入项目各个开发人员的相关主题样式文件,该文件是作为统一的入口。

components.less中引入antd.theme.less

// 引入项目各个开发人员的相关主题样式文件
@import './antd.theme.less';

说明:为啥是 public 目录呢?因为 Umi 项目,public 目录下所有文件会被 copy 到输出路径,也就是相关的资源,是被直接放到项目根目录。

2.编写 Utils 方法

在根目录下新建utils目录,在里面新建changeTheme.ts文件,下面的方法主要是动态插入less.min.js,动态插入自定义的相关样式,利用less.modifyVars方法,传入相关动态主题色参数,改变自定义的相关样式。

/**
 * 修改方法
 * @param type 被修改的样式
 * @param color 目标颜色
 */
function _changeTheme({ type, color }: { type: string, color: string }) {
  // 如果 window.less 未开启 直接返回空
  if (!(window as any).less) return;

  // 使用modifyVars方法,是基于 less 在浏览器中的编译来实现。
  // 所以在引入less文件的时候需要通过link方式引入,
  // 然后基于less.js中的方法来进行修改变量
  let a = {}
  switch (type) {
    case '@primary-color': a = {
      '@primary-color': color,
    }
      break;
    case '@text-color': a = {
      '@text-color': color,
    }
      break;
  }
  (window as any).less.modifyVars(a)
}

// 设置状态参数
let lessNodesAppended: boolean = false;
/**
 * 引入样式文件
 * @param type 被修改的样式
 * @param color 目标颜色
 */
export function onChangeTheme({ type, color }: { type: string, color: string }) {
  // 如果状态参数为 false 没有主题样式文件,引入状态文件
  if (!lessNodesAppended) {
    // 创建覆盖样式的less文件
    const lessStyleNode = document.createElement('link');
    lessStyleNode.setAttribute('rel', 'stylesheet/less');
    lessStyleNode.setAttribute('href', '/styles/components.less'); // public 目标下

    // 创建开启less配置
    const lessConfigNode = document.createElement('script');
    lessConfigNode.innerHTML = `
      window.less = {
        env: 'production',
        async: true,
        javascriptEnabled: true
      };
    `;
    // 引入 less.min.js
    const lessScriptNode = document.createElement('script');
    lessScriptNode.src = '/less.min.js';
    lessScriptNode.async = true;
    lessScriptNode.onload = () => {
      // 调用修改主题色方法
      _changeTheme({ type, color });
      lessScriptNode.onload = null;
    };
    // 插入 less.js,和 颜色主题.less
    document.body.appendChild(lessStyleNode);
    document.body.appendChild(lessConfigNode);
    document.body.appendChild(lessScriptNode);
    // 将状态参数变为 true
    lessNodesAppended = true;
  } else {
    // 状态参数为 true 已有主题样式文件,直接调用方法更改主题颜色
    _changeTheme({ type, color });
  }
}

3.修改主题颜色

在需要的地方引入、调用方法修改主题颜色

import { onChangeTheme } from '@/utils/changeTheme';
/**
 * 修改方法
 * @param type 被修改的样式
 * @param color 目标颜色
 */
onChangeTheme({ type: '@primary-color', color: e.target.value });

在微前端项目Bsin-PaaS的基座搭建中使用过此方法,对微前端有兴趣的朋友可以去看看Bsin-PaaS这个开源项目。
项目开源地址:gitee.com/bsin-paas/a…
线上演示地址:operation.flyray.me/
登录账号:
租户: bsin-paas
账户: admin
密码: 123456

d78d0b2b651f3cefa8f9208cbafa408.png