如何使用 clsx 正确加入 tailwind css 类?

frr*_*tyy 10 reactjs next.js tailwind-css

我正在尝试加入顺风类并使用clsx将它们应用到按钮。默认应用一个类\'rounded-none\',另一个类作为 prop 传入

\n
const Button = ({\n  children, ...props\n}): JSX.Element => {\n\n  return (\n    <ADButton\n      className={clsx(\'rounded-none\', props.className)}\n      {...props}\n    >\n      {children}\n    </ADButton>\n  );\n};\n
Run Code Online (Sandbox Code Playgroud)\n

假设我已经添加了padding-top: 0px;到按钮,如下所示

\n
<Button\n  color="primary"\n  className="pt-0"\n>\n  {t(\'btn.add\')}\n</Button>\n
Run Code Online (Sandbox Code Playgroud)\n

加入的类名应该是这样的\'rounded-none pt-0\'。如果没有传递 className 属性,则只需应用 \xe2\x80\x98rounded-none\xe2\x80\x99

\n

现在遇到的问题是 \xe2\x80\x98rounded-none\xe2\x80\x99 仅适用于没有 className 属性的按钮。在带有 className 属性的按钮上,仅应用 className 属性,但不应用 \xe2\x80\x98rounded-none\xe2\x80\x99。我怎样才能解决这个问题,以便两个类都加入并应用于按钮?

\n

Dah*_*her 16

您可以使用 clsx 和 twMerge twMerge的合并来有效地合并 JS 中的 Tailwind CSS 类,而不会发生样式冲突。小心不要覆盖你以前的课程

import clsx, { ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export const cn = (...classes: ClassValue[]) => twMerge(clsx(...classes))
Run Code Online (Sandbox Code Playgroud)


nel*_*les 5

您遇到此问题是因为默认属性ADButton设置为className,并且您传递给 Button 组件的额外属性也设置为className。实际上,您正在使用新传递的prop覆盖默认值。如果有 2 个类似名称的 props,React 将选择稍后在发生冲突时声明的一个。classNameclassName

所以这:

<ADButton
      className={clsx('rounded-none', 'pt-0')}
// I am declared later so I win
      className='pt-0'
    >
      {children}
    </ADButton>
Run Code Online (Sandbox Code Playgroud)

变成:

<ADButton
      className="pt-0"
    >
      {children}
    </ADButton>
Run Code Online (Sandbox Code Playgroud)

这是一种解决方案:

const Button = ({
  children, ...props
}) => {
  const { classNameDestructured = "", ...rest } = props;
  return (
    <ADButton
      className={clsx('rounded-none', classNameDestructured)}
      {...rest}
    >
      {children}
    </ADButton>
  );
};
Run Code Online (Sandbox Code Playgroud)

您解构props并设置默认值classNameDestructuredButton这允许您无需额外的 props即可声明:

<Button>
  {t('btn.add')}
</Button>
Run Code Online (Sandbox Code Playgroud)

然后您将classNameDestructured其作为参数传递给您的clsx()函数。然后,您的附加类将被加入并应用到按钮。

这是有效的,因为className不再作为 prop 声明两次,ADButton所以我们消除了最重要的冲突。