这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天
青训营大项目笔记
组件库通常而言我们是直接调用的,如vue里面可能用element plus,react里面可能直接用antd,但是如何开发属于我们自己的一套组件库呢?
环境准备
- 使用git版本控制
- 使用webpack进行打包
- 使用dumi生成文档站
- 使用npm管理包
- 使用eslint,stylelint,pretty来规范代码格式
- 使用jtest进行单元测试
- less进行样式组织
开发过程
一切都是从无到有的,我们团队在开发时考虑到个人技术水平的不一致,而且为了统一和规范,我们先开发了一个button组件,以这个作为最基础的demo在此之上进行开发
比方说我们的目录结构如下
一个典型的button组件需要导出,在button底下的index.tsx中引入button.tsx并导出,button.tsx作为我们button组件的主要逻辑开发部分,__ test __ 文件夹下存放测试所需内容,组件的测试通常包括能否正确渲染,能否正确进行回调。
组件基本需要配套的站点,所以我们在demos底下存放用于在站点上展示的内容,index.md中是文档站主要内容,里面可以引用demos中的文件,展示效果的同时也可以展示代码片段。
style目录下书写样式相关部分,通常而言是导入全局样式,然后再定制自己的样式,对使用到的新建变量再重新写回到根目录style下。
如这里的按钮样式
@import './mixins.less';
.l-btn {
position: relative;
display: inline-block;
color: @body-color;
font-weight: @btn-font-weight;
line-height: @btn-line-height;
white-space: nowrap;
text-align: center;
vertical-align: middle;
background-image: none;
border: @btn-border-width solid transparent;
box-shadow: @btn-box-shadow;
cursor: pointer;
transition: @btn-transition;
.button-size(@btn-padding-y, @btn-padding-x, @btn-font-size, @border-radius);
&.disabled,
&[disabled] {
box-shadow: none;
cursor: not-allowed;
opacity: @btn-disabled-opacity;
> * {
pointer-events: none;
}
}
}
// type
.l-btn-default {
.button-style(@white, @gray-400, @body-color, @white, @primary, @primary);
}
.l-btn-primary {
.button-style(@primary, @primary, @white);
}
.l-btn-info {
.button-style(@info, @info, @white);
}
.l-btn-warning {
.button-style(@warning, @warning, @white);
}
.l-btn-danger {
.button-style(@danger, @danger, @white);
}
.l-btn-text {
.button-style(transparent, transparent, @body-color);
box-shadow: none;
}
.l-btn-dashed {
.button-style(@white, @gray-400, @body-color, @white, @primary, @primary);
border-style: dotted;
}
.l-btn-link {
color: @btn-link-color;
font-weight: @font-weight-base;
text-decoration: none;
background-color: transparent;
box-shadow: none;
&:hover {
color: @btn-link-hover-color;
text-decoration: @link-hover-decoration;
}
&:focus,
&.focus {
text-decoration: @link-hover-decoration;
box-shadow: none;
}
&:disabled,
&.disabled {
color: @btn-link-disabled-color;
pointer-events: none;
}
}
// size
.l-btn-lg {
.button-size(
@btn-padding-y-lg,
@btn-padding-x-lg,
@btn-font-size-lg,
@btn-border-radius-lg
);
}
.l-btn-md {
.button-size(
@btn-padding-y-md,
@btn-padding-x-md,
@btn-font-size-md,
@btn-border-radius-md
);
}
.l-btn-sm {
.button-size(
@btn-padding-y-sm,
@btn-padding-x-sm,
@btn-font-size-sm,
@btn-border-radius-sm
);
}
// shape
.l-btn-circle {
min-width: 32px;
padding-right: 0;
padding-left: 0;
text-align: center;
border-radius: 50%;
}
.l-btn-round {
border-radius: 30%;
}
// block
.l-btn-block {
width: 100%;
}