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 代码更清晰、更可维护
