模仿一个ant-design-vue按钮组件
- 分析按钮组件需求
1.button 的样式与 ant-design-vue 的样式基本一致
高 32px
2.内容左右居中,上下也居中
3.文字大小跟设计稿一致
4.按钮被 hover 后跟设计稿一致
5.按钮被按下时有样式变化
6.按钮里的 icon 可以设置左右位置
7.按钮有一个loading状态
- 创建一个button.vue文件内容如下
<template>
<button class="h-buttom h-buttom-primary" :disabled='loading' @click="$emit('click',this)">
<h-icon v-if="icon&&!loading" :icon='icon' :loading='loading' :iconPosition='iconPosition'></h-icon>
<h-icon v-if="loading" :loading='loading' icon='H-Uiloading' :iconPosition='iconPosition'></h-icon>
<div class="h-ButtomSlot">
<slot></slot>
</div>
</button>
</template>
<script>
export default {
props:{
icon:{
type:String,
},
loading:{
type:Boolean,
default:false
},
iconPosition:{
type:String,
default:'left',
validator(val) {
return val === 'left' || val === 'right'
}
}
}
}
</script>
<style lang = "scss">
html{
--h-buttom-fontsize:14px;
--h-buttom-height:32px;
--h-buttom-bgcolor:#1890ff;
--h-buttom-bgcolor:#1890ff;
--h-buttom-color:#fff;
--h-buttom-color-active:#8890ff;
--h-buttom-color-hover:#6690ff;
--h-buttom-border-radius:4px;
}
.h-buttom[disabled] {
pointer-events: none;
cursor: not-allowed;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
opacity: .65;
}
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.h-buttom {
font-size: var(--h-buttom-fontsize);
background: var(--h-buttom-color);
border-radius: inherit;
height: var(--h-buttom-height);
margin-right: 8px;
margin-bottom: 12px;
display: inline-flex;
justify-content: center;
vertical-align: middle;
align-items: center;
padding: 0 1em;
border-radius: var(--h-buttom-border-radius);
cursor: pointer;
outline: none;
border: none;
border: 1px solid #d9d9d9;
& .h-ButtomSlot{
order: 2;
}
&:hover{
border-color: var(--h-buttom-bgcolor);
}
&:active{
color: var(--h-buttom-color-active);
}
/* icon 通过class设置左右位置 */
& .H-buttom-left{
order: 1;
margin-right: .5em;
}
& .H-buttom-right{
order: 3;
margin-left: .5em;
}
}
.h-buttom-primary{
color: #fff;
background-color: #1890ff;
border-color: #1890ff;
/* 按钮hover样式 */
&:hover{
color: #fff;
background-color: var(--h-buttom-color-hover);
}
/* 按钮按下样式 */
&:active{
color: #fff;
background-color: var(--h-buttom-color-active);
}
}
</style>
- 创建一个按钮图标icon组件icon.vue文件内容如下
<template>
<svg class="icon" :class="{[`H-buttom-${iconPosition}`]:true,[`H-buttom-loading`]:loading}">
<use :xlink:href='`#${icon}`'></use>
</svg>
</template>
<script>
export default {
name: '',
props:{
icon:{
type:String,
},
//通过loading来修改class设置loading动画
loading:{
type:Boolean,
default:false
},
iconPosition:{
type:String,
default:'left',
//validator 用来检查校验props的正确性
validator(val) {
return val === 'left' || val === 'right'
}
}
}
}
</script>
<style lang = "scss">
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
@keyframes loading {
0% {transform:rotate(0deg)}
100% {transform:rotate(360deg)}
}
.H-buttom-loading{
animation: 1s loading infinite forwards normal;
}
</style>