antd按需引入和自定义antd类名
一:antd样式引入有两个方式
-
一次性全部引入(不推荐)
- 一次性全部引入
antd
的样式,打包的时候样式文件会变得很庞大,导致第一次加载的时候需要的时间很长,用户体验差
- 一次性全部引入
// 入口样式文件引入样式
@import 'antd/dist/antd.less';
-
按需引入(推荐)(使用了
tree shaking
原理自动过滤没有被引入的样式)- 按需引入
antd
的样式,打包的时候只有被使用的组件的样式才会被打包进样式文件,样式文件会小很多,第一次加载时间会快很多,用户体验有所提升
- 按需引入
// .babelrc.js
// 安装插件yarn add babel-plugin-import
module.exports = {
// 这个配置是使用antd额按需加载
"plugins":[
[
"import",
{
"libraryName": "antd",
// 这个"style": true默认是使用less,还可以改成"style": "css"
"style": true
}
]
]
}
// 就这样按需加载就搞定了,不信你可以打包项目看看css代码哦
二:antd自定义类名
- 需要自定义
antd
类名的场景- 封装公用组件,为了防止样式攻击(避免组件里面的样式影响业务代码里面的样式)
// webpack.config.js
{
loader: 'less-loader',
options: {
lessOptions:{
javascriptEnabled: true,
modifyVars: {
// 以下两个配置使用前提是必须在按需引入那里配置"style": true,否则不起作用,因为这里要是用less变量
// @primary-color是设置antd的主题色,默认是蓝色的
// @ant-prefix是自定义antd组件类名前缀的,需要配合<ConfigProvider prefixCls="ymx">使用
"@primary-color": "red",
"@ant-prefix": "ymx",
},
}
},
}
-
这个自定义类名配置的原理
<ConfigProvider prefixCls="ymx">
里面的prefixCls
是改变jsx
文件里面的dom
节点的className
名称"@ant-prefix": "ymx",
这里只是改变打包css文件里面代码的前缀
-
看看在入口组件配置配置
<ConfigProvider prefixCls="ymx">
和webpack.config.js
里面配置"@ant-prefix": "ymx",
之后的效果(1)浏览器控制台看到的样子:
(2)打包后的css
代码,class
由ant
变成了ymx
-
红色框框:组件内部没有使用
prefixCls
class="ant-btn"变成了class="ymx-btn"
class="ant-collapse ant-collapse-icon-position-left"变成了class="ymx-collapse ymx-collapse-icon-position-left"
-
蓝色框框:直接在组件内部配置
prefixCls="innerPrefixCls"
class="ant-collapse ant-collapse-icon-position-left"变成了class="innerPrefixCls innerPrefixCls-icon-position-left"
-
-
接下来用一个
antd/github
上的比较简单的Collapse
组件源码来讲解为啥配置上面两项就可以达到修改antd
类名
源码地址:
由于涉及到的代码量还是有点多,这里就摘抄里面的关键部分
ConfigProvider
源码里面的getPrefixCls
方法,这个方法意思是如果组件内部用户使用了自定义类名customizePrefixCls
,那么类名就使用customizePrefixCls
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls;
return suffixCls ? `ant-${suffixCls}` : 'ant';
},
ConfigProvider
源码里面的getPrefixClsWrapper
方法,这个方法意思是组件里面使用customizePrefixCls
,则使用customizePrefixCls
,组件里面没有使用则根据ConfigProvider
上的prefixCls
计算mergedPrefixCls
,如果组件里面没有则mergedPrefixCls=prefixCls
,否则mergedPrefixCls=context.getPrefixCls('')
----就是ant
const getPrefixClsWrapper = (context: ConfigConsumerProps) => {
return (suffixCls: string, customizePrefixCls?: string) => {
const { prefixCls } = props;
if (customizePrefixCls) return customizePrefixCls;
const mergedPrefixCls = prefixCls || context.getPrefixCls('');
return suffixCls ? `${mergedPrefixCls}-${suffixCls}` : mergedPrefixCls;
};
};
Collapse
部分源码
// Collapse源码里面获取prefixCls
// 这里表示获取prefixCls,getPrefixCls是获取prefixCls的一个方法,如果用户有自定义customizePrefixCls,则前面的默认值collapse会被覆盖
const prefixCls = getPrefixCls('collapse', customizePrefixCls);
// Collapse源码里面的重组className
const collapseClassName = classNames(
{
[`${prefixCls}-borderless`]: !bordered,
[`${prefixCls}-icon-position-${iconPosition}`]: true,
[`${prefixCls}-rtl`]: direction === 'rtl',
[`${prefixCls}-ghost`]: !!ghost,
},
className,
);
// Collapse源码里面的render方法,把重组的className给到组件
<RcCollapse
openAnimation={openAnimation}
{...props}
expandIcon={(panelProps: PanelProps) => renderExpandIcon(panelProps)}
prefixCls={prefixCls}
className={collapseClassName}
/>