1、前言
学习并使用Vue有一段时间了,并且使用过Element UI,iview,ant-design等UI框架,然后就想着自己也做一套自己的UI框架,也算是对自己这么久学习Vue框架的一个总结。在写该组件库的时候,也踩过很多坑,碰到过一些以前使用Vue未曾碰到的问题,因此,这一系列的文章主要是记录下自己在造轮子过程中遇到的问题及思路。之后的每篇文章都会按照需求,实现,遇到的问题这三个角度来写,今天就先以Button组件开始吧。
2、Button组件-需求
在我使用过其他框架来看,按钮主要有以下几个方面的需求:
- 可点击/不可点击
- 按钮的类型
type - 按钮的大小
size loading状态icon图标(位置)hover状态- 按下按钮的状态
以上就是我在做Button组件时想到的几个点,当然没有考虑的很全面,但是能满足基本的使用。
3、Button组件-实现
首先想一下用户使用组件的API,大概就是如下进行调用:
<y-button>点我</y-button>
<y-button type="xxx">点我</y-button>
<y-button size="xxx">点我</y-button>
<y-button icon="xxx">点我</y-button>
<y-button disabled>点我</y-button>
<y-button loading>点我</y-button>
知道用户怎么使用按钮之后,接下来就是代码实现了。Button组件的实现还是相对于比较容易的,主要是一些css样式的编写,js部分的话主要是对事件的处理。
好了,话不多说,直接上代码:
<button
class="y-button"
:class="classes"
@click="onClick"
:disabled="disabled"
>
<y-icon class="icon" v-if="icon && !loading" :name="icon"></y-icon>
<y-icon class="loading icon" v-if="loading" name="loading"></y-icon>
<div class="content">
<slot></slot>
</div>
</button>
接收的参数如下:
props: {
icon: {
type: String,
default: '',
},
loading: {
type: Boolean,
default: false,
},
iconPosition: {
type: String,
default: 'left',
validator(value) {
return value === 'left' || value === 'right'
},
},
disabled: {
type: Boolean,
default: false,
},
size: {
type: String,
default: 'middle',
validator(value) {
return ['large', 'middle', 'small'].indexOf(value) >= 0
},
},
type: {
type: String,
default: 'default',
validator(value) {
return (
[
'dashed',
'text',
'primary',
'default',
'info',
'error',
'warning',
'success',
].indexOf(value) >= 0
)
},
},
}
具体含义如下:
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| size | 尺寸 | string | small / middle / large | middle |
| type | 类型 | string | primary / success / warning / error / info / text / dashed /default | default |
| disabled | 是否禁用状态 | boolean | — | false |
| icon | 图标名称 | string | — | — |
| iconPosition | 图标位置 | string | left / right | left |
| loading | 是否加载中状态 | boolean | — | false |
下面我就对代码做下解释,
- 给
button一个动态的class,这个class是由computed计算属性得来,
computed: {
classes() {
return {
[`icon-${this.iconPosition}`]: true,
['disabled']: this.disabled,
[`y-button-${this.size}`]: true,
[`y-button-${this.type}`]: true,
}
},
},
这个的意思就是,根据用户传的参数来生成对应的class,然后在css中写对应的样式就可以了。
-
button里面的两个icon组件,后面会介绍,主要是用来显示图标,第一行主要是控制按钮不在loading状态下显示图标(如果用户传了的话),第二行主要是控制显示loading图标的。 -
第三部分的
slot就是用来显示按钮上面的文字。 -
还有一个
click事件的监听,这里只是向外触发了一个事件,具体需要什么操作,根据用于自己实现,
onClick() {
console.log('kk')
if (this.disabled) {
console.log('kk')
return
}
this.$emit('click')
},
- 后面的就是
css样式的编写,具体的样式这里就不放出了,自己写的样式也不太好看,如果有兴趣的可以查看结尾的GitHub地址,代码都上传在那里。
到此,Button组件就已经造完了,是不是很简单哈!
4、Button组件-遇到的问题
说实话,写这个组件的时候还没有遇到困难的问题,难一点的可能就是各种类型下的按钮样式了吧,一些设计上还是借鉴了其他的组件库,因为自己设计的实在是太丑了。
5、结束
第一次写这种技术类的文章,不太清楚应该怎么写好,有什么问题的可以私信或者留言,然后在更新后面组件文章会进行调整。
项目地址Yue UI