Button组件

需求分析

Button组件大部分关注样式,没有交互。我们可以分析得到Button组件具体的属性列表:

  • type:不同的样式(primary、danger、warning、info、success)
  • size:不同的尺寸(large、small、default)
  • plain:是否为朴素按钮(样式的不同展现模式)
  • round:是否开启圆角
  • circle:是否圆形按钮
  • disabled:是否禁用
  • loading:是否为加载中状态
  • icon:图标组件

Button组件的本质

Button组件的本质其实就是class类名的组合

1
<button class="tm-button tm-button--primary tm-button--large is-plain is-disabled">按钮</button>

初始化项目

分析完了需求以后,我们就开始着手写代码,先使用脚手架工具初始化一个vite + vue3 + typescript + eslint的项目。

1
2
3
4
5
6
7
npm create vue@latest
#or
pnpm create vue@latest
#or
yarn create vue@latest
#or
bun create vue@latest

确定项目文件结构

  • components
    • Button
      • Button.vue 组件
      • style.css 样式
      • types.ts 一些辅助的typescript类型
      • Button.test.ts 测试文件

书写组件结构
实际上button组件就是在原生的button标签上面绑定了一些样式,内容直接用插槽来渲染即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
<button
ref="_ref"
class="vk-button"
:class="{
[`vk-button--${type}`]: type,
[`vk-button--${size}`]: size,
'is-plain': plain,
'is-round': round,
'is-circle': circle,
'is-disabled': disabled,
'is-loading': loading
}"
:disabled="disabled || loading"
:autofocus="autofocus"
:type="nativeType"
>
<Icon icon="spinner" spin v-if="loading" />
<Icon :icon="icon" v-if="icon" />
<span>
<slot />
</span>
</button>
</template>

添加css色彩变量
全局的样式写在src/styles目录下,结构如下:

  • styles
    • index.css 引用其他样式文件并在main.ts中引入
    • reset.css 重置浏览器样式
    • vars.css css色彩变量

为Button组件添加样式
我们的Button组件的样式写在src/components/Button/style.css文件中。

使用PostCss生成对应的css颜色变量
安装postcss相关依赖:

1
npm install postcss postcss-each-variables postcss-for postcss-nested postcss-color-mix postcss-each

postcss.config.cjs文件中使用这些插件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* eslint-env node */
module.exports = {
plugins: [
require('postcss-each-variables'),
require('postcss-nested'),
require('postcss-each')({
plugins: {
beforeEach: [
require('postcss-for'),
require('postcss-color-mix')
]
}
}),
]
}