tailwind-merge
(twMerge()
)是专门用于 去除 Tailwind 冲突样式 的工具。例如:
import { twMerge } from 'tailwind-merge';
console.log(twMerge('px-4 px-8 py-2 bg-blue-500 bg-red-500'));
// ✅ 结果: "px-8 py-2 bg-red-500"
// ❌ 直接用 `classnames` 会保留所有类,导致 `px-4` 和 `px-8` 冲突
twMerge()
让 Tailwind 类不会冲突,提高样式可控性!
例子:
定义一个 classnames.ts
文件,命名为 classNames
函数。
import { twMerge } from 'tailwind-merge';
import cn from 'classnames';
const classNames = (...cls: cn.ArgumentArray) => {
return twMerge(cn(cls));
};
export default classNames;
这个 classNames
函数的作用是 合并多个 CSS 类,同时避免 Tailwind 样式冲突,它结合了 classnames
和 tailwind-merge
,从而在 React 组件中更高效地管理 className
。
1. 避免 className
冲突
如果只用 classnames
,可能会导致 重复或冲突的 Tailwind 样式:
cn('px-4 px-8 py-2 bg-blue-500 bg-red-500');
// ❌ 结果: "px-4 px-8 py-2 bg-blue-500 bg-red-500" (冲突)
而 twMerge(cn(...))
会自动去重:
twMerge(cn('px-4 px-8 py-2 bg-blue-500 bg-red-500'));
// ✅ 结果: "px-8 py-2 bg-red-500"
2. 统一封装,代码更清晰
使用 classNames()
让代码更整洁:
const buttonClasses = classNames(
buttonVariants({ variant, size, className }),
destructive && 'btn-destructive'
);
等价于:
const buttonClasses = twMerge(cn(
buttonVariants({ variant, size, className }),
destructive && 'btn-destructive'
));
统一封装 classNames()
后,代码更直观,避免多处手写 twMerge(cn(...))
。
结论
这个 classNames
的封装主要是:
- 合并多个
className
,支持条件拼接 - 自动去除
false
、null
、undefined
,防止冗余 - 解决 Tailwind 类冲突(
twMerge
),提高样式可控性 - 让 React 代码更清晰、更可维护