Tailwind Css 中使用 Element Plus 主题系统的方案与实现

前言

本篇文章主要讲解在 Tailwind Css 中配置 Element Plus 主题变量以统一视觉设计

本文也是《通俗易懂的中后台系统建设指南》系列的第九篇文章,该系列旨在告诉你如何来构建一个优秀的中后台管理系统

需求概括

上一篇文章中我们讲解了生成 Element Plus 主题色阶和动态切换主题色:一篇文章实现 Element Plus 色彩动态切换

Clean Admin 中使用 Tailwind Css 来编写大部分样式

如果你不知道 Tailwind Css ,应该看看这个:Tailwind Css 官网

Tailwind Css 预设了多套色彩方案,但为了保持整个系统的色调、视觉设计统一,我们希望在 Tailwind Css 中能够使用 Element Plus 的主题变量

比如编写一个盒子卡片样式,盒子边框颜色 border-el-border-light 和字体颜色 text-el-primary-500 都表示采用 Element Plus 主题变量

html 复制代码
    <div class="size-12 border border-solid border-el-border-light rounded-lg">
      <span class="text-el-primary-500">盒子</span>
    </div>

Clean Admin 目前停留在 tailwind 3.x 版本,后面配置都是基于此版本实现

Tailwind 主题与配置

Tailwind 文档有一篇文章介绍了 Tailwind 主题与配置,允许我们在 tailwind.config.js 中定制自己的主题

比如试着将 Element Plus 主题变量写入 Tailwind 主题配置

注意,这里使用的是 extend,意思是扩展 Tailwind 主题配置,而不改变原有的预设主题

js 复制代码
export default {
  theme: {
    extend: {
      colors: {
        'el-primary': {
          100: 'var(--el-primary-100)',
          200: 'var(--el-primary-200)',
        },
      },
    },
  },
}

这样手动配置确实有效,但缺乏灵活性,且工作量还是比较大的,我们的方案是通过函数来生成符合要求的配置

生成色阶函数

Clean Admin 中有一个 theme 文件夹,在这里新建一个 tailwind 文件,用于处理 Tailwind 相关配置

上篇文章我们已经生成了 1 ~ 9 的 el-color-primary 色阶

根据这段色阶,现在需要写一个函数来生成符合 Tailwind 配置格式的色阶对象

比如,一个 generateElPrimaryScale 函数

ts 复制代码
/** 颜色类型 */
type ElColorType = 'primary' | 'success' | 'warning' | 'danger' | 'info';

/** Element Plus 主题色权重 */
const EL_PRIMARY_COLOR_WEIGHT = [100, 200, 300, 400, 500, 600, 700, 800, 900];

/**
 * 生成 Element Plus 主色、辅助色-色阶(primary、success、warning、danger、info)
 * @param colorType 主色、辅助色类型
 * @param weights 权重
 * @returns 颜色色阶
 */
export function generateElPrimaryScale(
  colorType: ElColorType = 'primary',
  weights: number[],
): Record<number | string, string> {
  const colorVariableScale: Record<number | string, string> = {};

  colorVariableScale.DEFAULT = `var(--el-color-${colorType})`;

  colorVariableScale['dark-200'] = `var(--el-color-${colorType}-dark-2)`;

  weights.forEach((weight) => {
    colorVariableScale[weight] = `var(--el-color-${colorType}-light-${weight / 100})`;
  });

  return colorVariableScale;
}

/** Tailwind 主题配置 */
export const tailwindThemeConfig: Config['theme'] = {
  extend: {
    colors: {
      /** 主题色 */
      'el-primary': generateElPrimaryScale('primary', EL_PRIMARY_COLOR_WEIGHT),
    }
  },
};

这里的 generateElPrimaryScale 函数,主要用于生成 Element Plus 主色、辅助色等色阶

EL_PRIMARY_COLOR_WEIGHT 是主颜色的权重,每个色梯都对应着一个 Element Plus Css 变量

el-primary 是样式前缀,比如要调用主颜色的 300 色阶,就可以写 text-el-primary-300,语法是 text-el-primary-[权重]

ts 复制代码
  console.log(generateElPrimaryScale('primary', EL_PRIMARY_COLOR_WEIGHT));

打印这个函数的返回值,输出的结构如下

现在,还差最后一步:把 tailwindThemeConfig 配置到 tailwind.config.js

tailwind.config.js 是 Tailwind Css 的配置文件,一般放在根目录下

js 复制代码
import { tailwindThemeConfig } from './src/theme/tailwind';

/** @type {import('tailwindcss').Config} */
export default {
  theme: {
    ...tailwindThemeConfig,
  },
};

截止到这一步,配置工作已经完成,测试一下 Tailwind Css 中是否生效

  1. 根据 IDE 中 Tailwind 插件的提示,检查是否生效(下图效果)
  2. 使用 Tailwind Css 方式写入 Element Plus 主题变量,观察在浏览器的样式效果

注意,这里默认你在 VSCode、Cursor 中安装了 Tailwind 插件,能够自动提示

比如我们希望把一段文本颜色设置为默认主题色,可以这样做

其他辅助色

Element Plus 除了主颜色外,还存在一些辅助色,比如 成功色(Success)、警告色(Warning)、危险色(Danger)、信息色(Info)

和上面的配置操作一样,我们已经有了色阶函数,只需要把剩下颜色都配置到 tailwindThemeConfig 中即可

Clean Admin 中针对主颜色分了 9 个色阶,辅助色(Success、Warning、Danger、Info)等则根据 Element Plus 默认分为了 5 个色阶

ts 复制代码
/** Element Plus 辅助色权重 */
const EL_ASSISTANT_COLOR_WEIGHT = [300, 500, 700, 800, 900];

/** Tailwind 主题配置 */
export const tailwindThemeConfig: Config['theme'] = {
  extend: {
    colors: {
      //...
      /** 成功色 */
      'el-success': generateElPrimaryScale('success', EL_ASSISTANT_COLOR_WEIGHT),
      /** 警告色 */
      'el-warning': generateElPrimaryScale('warning', EL_ASSISTANT_COLOR_WEIGHT),
      /** 危险色 */
      'el-danger': generateElPrimaryScale('danger', EL_ASSISTANT_COLOR_WEIGHT),
      /** 信息色 */
      'el-info': generateElPrimaryScale('info', EL_ASSISTANT_COLOR_WEIGHT),    }
  },
};

Clean Admin 中关于此部分的代码:点击查看

Element Plus 中性色配置

翻开 Element Plus 官网的色彩篇

Element Plus 主题系统中除了主颜色、辅助颜色,还提供了中性色,包括文本、边框、填充、背景等

前面部分给出的色阶函数,只适用于主颜色、辅助颜色,中性色的梯度有些不同,比如不是单纯用色阶数字来表示层级

这里再写一个针对中性色的函数

ts 复制代码
/**
 * 生成 Element Plus 中性色-色阶
 * @param colorType 中性色类型(border、bg、fill、text...)
 * @param weights 权重列表
 * @param hasDefault 是否包含默认值
 * @returns 颜色色阶
 */
export function generateElThemeScale(
  colorType: string,
  weights: number[] | string[],
  hasDefault: boolean = true,
): Record<number | string, string> {
  const colorVariableScale: Record<number | string, string> = {};

  hasDefault && (colorVariableScale.DEFAULT = `var(--el-${colorType}-color)`);

  weights.forEach((weight) => {
    colorVariableScale[weight] = `var(--el-${colorType}-color-${weight})`;
  });

  return colorVariableScale;
}

这个色阶函数中有一个参数 hasDefault ,默认为 true,用于决定是否包含默认值 DEFAULT,像文本色值,就不存在 --el-text-color 变量

通过在谷歌浏览器开发者工具中找到 Element Plus 的相关 Css 变量及权重,比如文本和边框

ts 复制代码
/** Element Plus 文本权重 */
export const EL_TEXT_WEIGHT = ['primary', 'regular', 'secondary', 'placeholder', 'disabled'];

/** Element Plus 边框权重 */
export const EL_BORDER_WEIGHT = ['darker', 'dark', 'light', 'lighter', 'extra-light'];

generateElThemeScale 函数生成中性色的色阶,然后在 tailwindThemeConfig 中配置

ts 复制代码
/** Tailwind 主题配置 */
export const tailwindThemeConfig: Config['theme'] = {
  extend: {
    //...
    textColor: {
      /** 文本色阶 */
      'el-text': generateElThemeScale('text', EL_TEXT_WEIGHT, false),
    },
    borderColor: {
      /** 边框色阶 */
      'el-border': generateElThemeScale('border', EL_BORDER_WEIGHT),
    },
  },
};

假设在一个 div 上写入边框和文本颜色

html 复制代码
    <div class="size-12 border border-solid border-el-border rounded-lg">
      <span class="text-el-text-primary">盒子</span>
    </div>

最后

写到这里,我们已经基本实现了在使用 Tailwind Css 中使用 Element Plus 变量的需求

可以在 vue-clean-admin/theme 文件夹中查看完整代码

参考资料

了解更多

系列专栏地址:GitHub 博客 | 掘金专栏 | 思否专栏

实战项目:vue-clean-admin

专栏往期回顾:

  1. 收下这份 Vue + TS + Vite 中后台系统搭建指南,从此不再害怕建项目
  2. 中后台开发必修课:Vue 项目中 Pinia 与 Router 完全攻略
  3. 用了这些 Vite 配置技巧,同事都以为我开挂了
  4. 受够了团队代码风格不统一?7千字教你从零搭建代码规范体系
  5. 开发者必看!在团队中我是这样实现 Git 提交规范化的
  6. 告别繁琐!Vue3 组合式函数解锁 Echarts 封装新姿势
  7. 彻底搞懂面包屑,手把手封装一个 Vue3 面包屑导航组件
  8. 一篇文章实现 Element Plus 动态切换主题色

交流讨论

文章如有错误或需要改进之处,欢迎指正

相关推荐
飏旎5 分钟前
Vue中computed和watch的区别
前端·javascript·vue.js
绍棠5 分钟前
uniapp转app时,cover-view的坑
前端·javascript·uni-app
_码农121389 分钟前
java web 未完成项目,本来想做个超市管理系统,前端技术还没学。前端是个简单的html。后端接口比较完善。
java·前端·html
CodeCraft Studio15 分钟前
DHTMLX重磅发布React Scheduler组件,赋能日程管理开发!
前端·react.js·前端框架·dhtmlx·调度·scheduler·排程
AKA大佬23 分钟前
学习vue2的准备工作-脚手架创建一个简单的vue2项目
前端·vue.js
Antonio91529 分钟前
【音视频】WebRTC 一对一通话-Web端
前端·音视频·webrtc
2503_9284115629 分钟前
8.5 CSS3-flex弹性盒子
前端·css·css3
盏灯32 分钟前
🎨数据可视化js库 - D3.js
前端
大熊学员34 分钟前
HTML总结全览
前端·css·html
2503_9284115635 分钟前
8.5 CSS3多列布局
前端·css·css3