# 按钮篇

# 设计细节

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

# 功能细节

  1. 支持icon的设置。比较常见的场景是icon在文案左边或者右边,这个可以通过传入一个iconPositionleftright来决定,一开始的想法是通过v-if来决定显示哪一行:
<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修改成如下:

<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时不出现其它图标的情况,增加一个判断条件:
<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°不断地旋转,那我们只要写一个旋转的动画处理就可以,如下:
@keyframes spin{
  0% {transform: rotate(0deg)}
  100% {transform: rotate(360deg)}
}

.loading {
  animation: spin 1s infinite linear;
}
  1. 按钮组合。按钮组合应该让按钮衔接看起来顺滑一点,这里采取的默认方案是按钮紧挨,然后第一个按钮和最后一个按钮的边缘钝化,同时中间的按钮应向前靠1像素,因为button都有border,看起来会很粗。代码如下:
<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组件说明。

具体内容请访问这里