Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《TypeScript》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《TypeScript》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • Tailwind CSS基础知识
  • Tailwind CSS Config
  • Tailwind 插件机制
    • 什么时候用?
    • 1️⃣ 最简单例子
    • 2️⃣ 支持响应式 / hover / dark
    • 3️⃣ 从 theme 中取值(核心)
    • 4️⃣ 批量生成 utilities(常用技巧)
    • 什么时候用?
    • 1️⃣ Button 组件例子(核心)
    • 2️⃣ 响应式组件
    • 3️⃣ Dark Mode 组件
      • 用来改默认标签样式
      • Tailwind 插件负责「样式规则」
      • Vue 组件负责「结构 + 逻辑」
      • 1️⃣ 插件生成的类也会被 purge?
      • 2️⃣ 插件 vs @apply 怎么选?
  • Tailwind 底层生成机制 & purge 原理
  • Tailwind结合 H5 rem/vw 的配置方案
  • H5 Tailwind preset
  • 《Tailwind CSS》
mamingjuan
2025-03-24
目录

Tailwind 插件机制

Tailwind 插件机制(addUtilities / addComponents) 属于 👉 “从会用 Tailwind → 能做组件库 / 规范体系” 的分水岭


# 一、插件机制是干嘛的?

一句话:

用 JS 批量生成 Tailwind 类,而不是手写 CSS

你可以:

  • 定义一组 工具类(utilities)
  • 定义一组 组件类(components)
  • 读 theme() 里的设计变量
  • 自动支持 hover / dark / responsive

# 二、插件基本结构

// tailwind.config.js
import plugin from 'tailwindcss/plugin'

export default {
  theme: { extend: {} },
  plugins: [
    plugin(function ({ addUtilities, addComponents, theme }) {
      // 写插件逻辑
    })
  ]
}
1
2
3
4
5
6
7
8
9
10
11

# 三、addUtilities(工具类)

# 什么时候用?

👉 单一功能、可自由组合的原子能力

如:

  • .safe-top
  • .text-shadow
  • .scrollbar-hide

# 1️⃣ 最简单例子

addUtilities({
  '.safe-top': {
    paddingTop: 'env(safe-area-inset-top)'
  }
})
1
2
3
4
5
<div class="safe-top"></div>
1

# 2️⃣ 支持响应式 / hover / dark

addUtilities(
  {
    '.text-shadow': {
      textShadow: '0 2px 4px rgba(0,0,0,.2)'
    }
  },
  ['responsive', 'hover', 'dark']
)
1
2
3
4
5
6
7
8
<div class="hover:text-shadow dark:text-shadow"></div>
1

# 3️⃣ 从 theme 中取值(核心)

addUtilities(
  {
    '.bg-primary-gradient': {
      background: `linear-gradient(
        90deg,
        ${theme('colors.primary.500')},
        ${theme('colors.primary.700')}
      )`
    }
  }
)
1
2
3
4
5
6
7
8
9
10
11

📌 这一步 = 插件 + 设计系统打通


# 4️⃣ 批量生成 utilities(常用技巧)

const sizes = {
  sm: '4px',
  md: '8px',
  lg: '16px'
}

addUtilities(
  Object.entries(sizes).map(([key, value]) => ({
    [`.blur-${key}`]: { filter: `blur(${value})` }
  }))
)
1
2
3
4
5
6
7
8
9
10
11

使用:

<div class="blur-md"></div>
1

# 四、addComponents(组件类)

# 什么时候用?

👉 一整套固定结构样式

如:

  • Button
  • Card
  • Alert
  • Tag

# 1️⃣ Button 组件例子(核心)

addComponents({
  '.btn': {
    padding: '8px 16px',
    borderRadius: theme('borderRadius.md'),
    fontWeight: '500'
  },
  '.btn-primary': {
    backgroundColor: theme('colors.primary.500'),
    color: '#fff',
    '&:hover': {
      backgroundColor: theme('colors.primary.700')
    }
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<button class="btn btn-primary"></button>
1

📌 btn = 结构 📌 btn-primary = 皮肤


# 2️⃣ 响应式组件

addComponents({
  '.card': {
    padding: '16px',
    '@screen md': {
      padding: '24px'
    }
  }
})
1
2
3
4
5
6
7
8

# 3️⃣ Dark Mode 组件

addComponents({
  '.card': {
    backgroundColor: '#fff',
    '.dark &': {
      backgroundColor: '#111'
    }
  }
})
1
2
3
4
5
6
7
8

# 五、addUtilities vs addComponents(重点对比)

维度 addUtilities addComponents
定位 原子能力 组件封装
组合性 强 弱
是否有语义 几乎无 强
适合场景 功能类 组件库

📌 经验法则

能拆 → utilities 不想拆 → components


# 六、addBase(顺带讲)

# 用来改默认标签样式

addBase({
  'h1': { fontSize: theme('fontSize.xl') },
  'h2': { fontSize: theme('fontSize.lg') }
})
1
2
3
4

📌 常用于:

  • reset
  • markdown 样式

# 七、实战:做一个「企业级按钮插件」

// plugins/button.js
import plugin from 'tailwindcss/plugin'

export default plugin(({ addComponents, theme }) => {
  addComponents({
    '.btn': {
      display: 'inline-flex',
      alignItems: 'center',
      justifyContent: 'center',
      borderRadius: theme('borderRadius.md'),
      padding: '8px 16px',
      fontWeight: '500'
    },
    '.btn-primary': {
      backgroundColor: theme('colors.primary.500'),
      color: '#fff',
      '&:hover': {
        backgroundColor: theme('colors.primary.700')
      }
    },
    '.btn-danger': {
      backgroundColor: theme('colors.danger.500'),
      color: '#fff'
    }
  })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// tailwind.config.js
import button from './plugins/button'

plugins: [button]
1
2
3
4

# 八、和 Vue 组件结合的最佳实践

# Tailwind 插件负责「样式规则」

# Vue 组件负责「结构 + 逻辑」

<button class="btn" :class="`btn-${type}`">
  <slot />
</button>
1
2
3

# 九、常见坑(你一定会遇到)

# 1️⃣ 插件生成的类也会被 purge?

✅ 不会(插件是构建时注入)


# 2️⃣ 插件 vs @apply 怎么选?

  • 公共体系 → 插件
  • 局部组件 → @apply
上次更新: 2025/12/26, 01:42:33
Tailwind CSS Config
Tailwind 底层生成机制 & purge 原理

← Tailwind CSS Config Tailwind 底层生成机制 & purge 原理→

Copyright © 2015-2025 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式