博客 / 詳情

返回

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 主題變量

    <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 主題配置,而不改變原有的預設主題

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 色階

image

根據這段色階,現在需要寫一個函數來生成符合 Tailwind 配置格式的色階對象

比如,一個 generateElPrimaryScale 函數

/** 顏色類型 */
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-[權重]

  console.log(generateElPrimaryScale('primary', EL_PRIMARY_COLOR_WEIGHT));

打印這個函數的返回值,輸出的結構如下

image

現在,還差最後一步:把 tailwindThemeConfig 配置到 tailwind.config.js

tailwind.config.js 是 Tailwind Css 的配置文件,一般放在根目錄下
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 插件,能夠自動提示

比如我們希望把一段文本顏色設置為默認主題色,可以這樣做

image

其他輔助色

Element Plus 除了主顏色外,還存在一些輔助色,比如 成功色(Success)、警告色(Warning)、危險色(Danger)、信息色(Info)

和上面的配置操作一樣,我們已經有了色階函數,只需要把剩下顏色都配置到 tailwindThemeConfig 中即可

Clean Admin 中針對主顏色分了 9 個色階,輔助色(Success、Warning、Danger、Info)等則根據 Element Plus 默認分為了 5 個色階

/** 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 主題系統中除了主顏色、輔助顏色,還提供了中性色,包括文本、邊框、填充、背景等

前面部分給出的色階函數,只適用於主顏色、輔助顏色,中性色的梯度有些不同,比如不是單純用色階數字來表示層級

image

這裏再寫一個針對中性色的函數

/**
 * 生成 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 變量及權重,比如文本和邊框

/** 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 中配置

/** 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 上寫入邊框和文本顏色

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

image

image

最後

寫到這裏,我們已經基本實現了在使用 Tailwind Css 中使用 Element Plus 變量的需求

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

參考資料

  • Element Plus - Color 色彩

瞭解更多

系列專欄地址: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 動態切換主題色

交流討論

文章如有錯誤或需要改進之處,歡迎指正

user avatar webxejir 頭像 esunr 頭像 coderleo 頭像 codepencil 頭像 chenychenyu 頭像 gaoming13 頭像 pugongyingxiangyanghua 頭像 iymxpc3k 頭像 wukongnotnull 頭像 warn 頭像 wupengyu_55d86cdb45293 頭像 mmmy_a 頭像
31 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.