拼合样式类名

如果在 React 组件中只使用 CSS Module 或者只使用普通样式类名,那么一般直接书写是没有问题的。但是如果要是混用 CSS Module 和通用样式类名,那么就需要对样式类名进行拼合了。

下面这种拼合是错误的,不能通过编译或者编译不出所需要的效果。

// 下面这样是不能通过编译的
<Button className={styles.primary} className="mt-1">Test Button</Button>

// 下面这样是没有效果的
<Button className="{styles.primary} mt-1">Test Button</Button>

如果的确需要这样使用,那么可以选择以下方法。

<Button className={[styles.primary, 'mt-1'].join(' ')}>Test Button</Button>

<Button className={`${styles.primary} mt-1`}>Test Button</Button>

如果觉得这种写法也不是那么爽,还可以利用 classnames 库来拼合。使用 classnames 库以后,上面的示例就会变成下面的样子。

<Button className={classnames(styles.primary, 'mt-1')}>Test Button</Button>;

要在项目中使用 classnames 可以直接使用 npm 安装。

npm install classnames
yarn add classnames

之后只需要在需要的文件中引入即可。

import classnames from 'classnames';

相对于classnames,还有一个更加简单的库可以使用:clsx。要在项目中使用clsx,可以直接使用npm安装。

npm install clsx
yarn add clsx

clsx支持更多种样式类名的组合方法,包括字符串、对象、数组等。具体可参考以下示例。

import clsx from 'clsx';

// 使用字符串拼接,每个字符串参数可以使用布尔表达式搭配 && 来确定其是否会被拼入
clsx('class-A', true && 'class-B', false && 'class-C');
// 将产生 'class-A class-B' 的字符串。

// 使用对象来描述,如果对象中字段的值是 true,那么这个字段的名称将被拼入
clsx({ classA: true, classB: isTrue() });
// 将产生 'classA classB' 的字符串,对于其中的函数将会自动求值。

// 使用多个对象进行拼合
clsx({ classA: true }, { classB: isTrue() });
// 同样会产生 'classA classB' 的字符串。

// 使用数组进行拼合,数组中的所有true值将会被拼入
clsx(['classA'], [1 && 'classB', { classC: true, classD: false }]);
// 会产生 'classA classB classC' 的字符串

总起来说,所有传入的false值都将不会被拼入最终的字符串,而且有用复杂嵌套结构的数组也会被展平。