开发一个UI框架项目[2]-Button

本文最后更新于:2020年9月12日 晚上

设计细节

  1. 高度最好为8的倍数,此处设置为32px;如果要支持大小类型的按钮,可设置为24px(small)和40px(large);
  2. 按钮不设置固定宽度,左右padding设置为1em,表示左右各留一个字的空间;
  3. 因为button设置为inline-flex布局,在多个按钮并列时会存在位置不对齐的问题,使用vertical-align: middle解决。

功能细节

  1. 支持icon的设置。比较常见的场景是icon在文案左边或者右边,这个可以通过传入一个iconPositionleftright来决定,一开始的想法是通过v-if来决定显示哪一行:
1
2
3
4
5
<button>
<yv-icon v-if="iconPosition === 'left'"></yv-icon>
<div class="button-content"></div>
<yv-icon v-if="iconPosition === 'right'"></yv-icon>
</button>

但是这种做法有点low,也多了一行没必要的重复代码,然后想到flex有一个order的属性,可以决定子元素布局的排列优先级,template修改成如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<button class="yv-button" :class="{[`icon-${iconPosition}`]: true}">
<div class="button-content">
<slot></slot>
</div>
<yv-icon class="icon"></yv-icon>
</button>
</template>
<style scoped lang="scss">
.yv-button {
> .button-content {
order: 2;
}
> .icon {
order: 1;
}
&.icon-right {
> .button-content {
order: 1;
}
> .icon {
order: 2;
}
}
}
</style>

一开始设置icon的order1表示默认icon是在左边,当用户传了iconPositionright时,就会给button加上
icon-rightclass名,这时icon的order设置为2contentorder设置为1,这样在不修改代码的情况下,通过order的值就可以设置icon的显示位置。

  1. 支持loading的设置。因为loading也要有图标,所以需要处理loading时不出现其它图标的情况,增加一个判断条件:
1
2
3
4
5
6
7
<button>
<div class="button-content">
<slot></slot>
</div>
<yv-icon class="icon" v-if="icon && !loading" :name="name"></yv-icon>
<yv-icon class="loading icon" v-if="loading" name="loading"></yv-icon>
</button>
  1. 让loading的图标动起来。因为iconfont上面的图标都是静态的,而loading是要动起来的。仔细想了一下,loading就是360°不断地旋转,那我们只要写一个旋转的动画处理就可以,如下:
1
2
3
4
5
6
7
8
@keyframes spin{
0% {transform: rotate(0deg)}
100% {transform: rotate(360deg)}
}

.loading {
animation: spin 1s infinite linear;
}
  1. 按钮组合。按钮组合应该让按钮衔接看起来顺滑一点,这里采取的默认方案是按钮紧挨,然后第一个按钮和最后一个按钮的边缘钝化,同时中间的按钮应向前靠1像素,因为button都有border,看起来会很粗。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<style scoped lang="scss">
$button-radius: 4px;
.yv-button-group {
display: inline-flex;
vertical-align: middle;
.yv-button {
border-radius: 0;
&:not(:first-child) {
margin-left: -1px;
}
&:first-child {
border-bottom-left-radius: $button-radius;
border-top-left-radius: $button-radius;
}
&:last-child {
border-top-right-radius: $button-radius;
border-bottom-right-radius: $button-radius;
}
}
}
</style>

人工测试

手动测试。。。已完成。

自动化测试

test文件夹下增加button.test.js文件。

主要增加7个测试用例,分别是:测试button是否存在设置iconicon初始位置设置icon位置设置loading设置disabledclick点击事件

运行npm run dev-test命令,是配置在package.json文件中的该命令:parcel watch test/* --no-cache & karma start,就是监听、打包test文件夹下的*.test.js文件,然后运行karma开始自动化测试,测试结果可在浏览器控制台查看:

浏览器控制台显示

或者powershell面板查看:

powershell显示

vuepress配置

docs/.vuepress/components文件夹下增加button-demo的vue文件,内容就是我们要展示的button示例,然后在docs/components文件夹下增加button的md文件,内容就是放置整个button组件说明。

具体内容请访问这里