Next.js SCSS模块化多类名冲突:如何让组件内置类与外部类共存?
解决HTag组件内置样式与外部类名冲突问题
问题出在你当前的组件写法中:先给标题元素设置了内置的styles.h1类名,之后展开...props时,如果props里包含className,会直接覆盖掉之前的className属性,导致内置样式被外部类名替换。
要让两类样式同时生效,需要合并内置类名与传入的外部类名,以下是两种实现方式:
方式一:用辅助函数合并类名
import {HTagProps} from './HTag.props' import styles from './HTag.module.scss' export const HTag = ({children, h, className, ...props}: HTagProps) => { // 合并内置类名和外部类名,自动处理无外部类名的情况 const combineClassNames = (baseClass: string) => { return className ? `${baseClass} ${className}` : baseClass } switch (h) { case 'h1': return (<h1 className={combineClassNames(styles.h1)} {...props}>{children}</h1>) case 'h2': return (<h2 className={combineClassNames(styles.h2)} {...props}>{children}</h2>) case 'h3': return (<h3 className={combineClassNames(styles.h3)} {...props}>{children}</h3>) case 'h4': return (<h4 className={combineClassNames(styles.h4)} {...props}>{children}</h4>) case 'h5': return (<h5 className={combineClassNames(styles.h5)} {...props}>{children}</h5>) case 'h6': return (<h6 className={combineClassNames(styles.h6)} {...props}>{children}</h6>) default: return <></> } }
方式二:用数组过滤拼接(更简洁)
利用数组过滤掉空值后拼接,避免出现多余空格:
import {HTagProps} from './HTag.props' import styles from './HTag.module.scss' export const HTag = ({children, h, className, ...props}: HTagProps) => { switch (h) { case 'h1': return (<h1 className={[styles.h1, className].filter(Boolean).join(' ')} {...props}>{children}</h1>) case 'h2': return (<h2 className={[styles.h2, className].filter(Boolean).join(' ')} {...props}>{children}</h2>) case 'h3': return (<h3 className={[styles.h3, className].filter(Boolean).join(' ')} {...props}>{children}</h3>) case 'h4': return (<h4 className={[styles.h4, className].filter(Boolean).join(' ')} {...props}>{children}</h4>) case 'h5': return (<h5 className={[styles.h5, className].filter(Boolean).join(' ')} {...props}>{children}</h5>) case 'h6': return (<h6 className={[styles.h6, className].filter(Boolean).join(' ')} {...props}>{children}</h6>) default: return <></> } }
原理说明
- 先从props中解构出
className,剩余属性用...props接收(此时props已不含className,不会再覆盖) - 将内置类名与外部类名组合成合法的多类名字符串,这样渲染后的元素会同时拥有两个类名,两类样式自然同时生效
内容的提问来源于stack exchange,提问作者Eva
相关产品推荐
相关产品推荐

