Tailwind CSS 可以与各种现代前端框架完美配合。本节将详细介绍如何将 Tailwind CSS 集成到 React、Vue 和 Angular 等主流框架中,并介绍相关的最佳实践。
React 集成
基础配置
bash
# 创建 React 项目
npx create-react-app my-app --template typescript
# 安装 Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
# 初始化 Tailwind CSS
npx tailwindcss init -p
javascript
// tailwind.config.js
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
css
/* src/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
组件开发
typescript
// src/components/Button.tsx
interface ButtonProps {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
children: React.ReactNode;
}
const Button: React.FC<ButtonProps> = ({
variant = 'primary',
size = 'md',
children
}) => {
const baseStyles = 'rounded-lg font-medium transition-colors';
const variants = {
primary: 'bg-blue-500 text-white hover:bg-blue-600',
secondary: 'bg-gray-500 text-white hover:bg-gray-600'
};
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg'
};
return (
<button className={`${baseStyles} ${variants[variant]} ${sizes[size]}`}>
{children}
</button>
);
};
export default Button;
样式组织
typescript
// src/styles/components.ts
export const buttonStyles = {
base: 'rounded-lg font-medium transition-colors',
variants: {
primary: 'bg-blue-500 text-white hover:bg-blue-600',
secondary: 'bg-gray-500 text-white hover:bg-gray-600'
},
sizes: {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg'
}
};
Vue 集成
项目配置
bash
# 创建 Vue 项目
npm init vue@latest
# 安装依赖
npm install -D tailwindcss postcss autoprefixer
# 初始化配置
npx tailwindcss init -p
javascript
// tailwind.config.js
module.exports = {
content: [
"./index.html",
"./src/**/*.{vue,js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
组件示例
vue
<!-- src/components/BaseButton.vue -->
<template>
<button
:class="[
baseStyles,
variants[variant],
sizes[size]
]"
>
<slot></slot>
</button>
</template>
<script setup lang="ts">
interface Props {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
}
const props = withDefaults(defineProps<Props>(), {
variant: 'primary',
size: 'md'
});
const baseStyles = 'rounded-lg font-medium transition-colors';
const variants = {
primary: 'bg-blue-500 text-white hover:bg-blue-600',
secondary: 'bg-gray-500 text-white hover:bg-gray-600'
};
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg'
};
</script>
自定义指令
typescript
// src/directives/tailwind.ts
import { DirectiveBinding } from 'vue'
export const vTailwind = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const value = binding.value
if (typeof value === 'string') {
el.className = value
} else if (typeof value === 'object') {
el.className = Object.entries(value)
.filter(([_, condition]) => condition)
.map(([className]) => className)
.join(' ')
}
},
updated(el: HTMLElement, binding: DirectiveBinding) {
// 同上
}
}
Angular 集成
项目设置
bash
# 创建 Angular 项目
ng new my-app
# 安装依赖
npm install -D tailwindcss postcss autoprefixer
# 初始化配置
npx tailwindcss init
javascript
// tailwind.config.js
module.exports = {
content: [
"./src/**/*.{html,ts}",
],
theme: {
extend: {},
},
plugins: [],
}
组件实现
typescript
// src/app/components/button/button.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-button',
template: `
<button [ngClass]="[
baseStyles,
variants[variant],
sizes[size]
]">
<ng-content></ng-content>
</button>
`
})
export class ButtonComponent {
@Input() variant: 'primary' | 'secondary' = 'primary';
@Input() size: 'sm' | 'md' | 'lg' = 'md';
baseStyles = 'rounded-lg font-medium transition-colors';
variants = {
primary: 'bg-blue-500 text-white hover:bg-blue-600',
secondary: 'bg-gray-500 text-white hover:bg-gray-600'
};
sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg'
};
}
服务封装
typescript
// src/app/services/tailwind.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class TailwindService {
combineClasses(...classes: (string | undefined)[]): string {
return classes.filter(Boolean).join(' ');
}
getColorClass(color: string, variant: string = '500'): string {
return `bg-${color}-${variant}`;
}
getTextClass(color: string, variant: string = '500'): string {
return `text-${color}-${variant}`;
}
}
框架通用最佳实践
样式抽象
typescript
// src/styles/theme.ts
export const theme = {
colors: {
primary: {
light: 'bg-blue-400',
default: 'bg-blue-500',
dark: 'bg-blue-600'
},
secondary: {
light: 'bg-gray-400',
default: 'bg-gray-500',
dark: 'bg-gray-600'
}
},
typography: {
sizes: {
sm: 'text-sm',
base: 'text-base',
lg: 'text-lg'
}
}
};
工具函数
typescript
// src/utils/tailwind.ts
export function classNames(...classes: (string | undefined)[]) {
return classes.filter(Boolean).join(' ');
}
export function createVariant(baseClass: string, variants: Record<string, string>) {
return (variant: keyof typeof variants) =>
classNames(baseClass, variants[variant]);
}
类型支持
typescript
// src/types/tailwind.ts
export type Color =
| 'primary'
| 'secondary'
| 'success'
| 'warning'
| 'danger';
export type Shade =
| '50'
| '100'
| '200'
| '300'
| '400'
| '500'
| '600'
| '700'
| '800'
| '900';
export type ColorClass = `bg-${Color}-${Shade}`;
export type TextClass = `text-${Color}-${Shade}`;
性能优化
按需加载
javascript
// tailwind.config.js
module.exports = {
content: [
// 精确指定需要处理的文件
"./src/components/**/*.{js,ts,jsx,tsx,vue}",
"./src/pages/**/*.{js,ts,jsx,tsx,vue}",
],
// 禁用未使用的核心插件
corePlugins: {
float: false,
clear: false,
objectFit: false
}
}
构建优化
javascript
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true
}
}
}
}
}
最佳实践
-
集成原则
- 遵循框架约定
- 保持代码一致性
- 合理的样式组织
-
开发建议
- 组件抽象
- 类型支持
- 工具函数复用
-
性能考虑
- 按需加载
- 代码分割
- 缓存优化
-
维护策略
- 统一的样式规范
- 组件文档
- 版本控制