组件代码:
<template>
<div class="gi-button" :class="getClass" :style="getStyle" @click="handleClick">
<i v-if="icon || loading" class="gi-button-icon" :class="getIconClass" :style="getIconStyle"></i>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'GiButton', // 通用按钮
props: {
// 按钮类型 默认default 虚线dashed 镂空outline 文本text
type: {
type: String,
default: 'default'
},
// 按钮状态 primary success warning danger info
status: {
type: String,
default: 'primary'
},
// 按钮图标
icon: {
type: String,
default: ''
},
// 按钮尺寸 mini small medium large
size: {
type: String,
default: 'mini'
},
// 按钮形状 矩形square 椭圆round 圆circle
shape: {
type: String,
default: 'square'
},
// 加载
loading: {
type: Boolean,
default: false
},
// 是否禁用
disabled: {
type: Boolean,
default: false
}
},
computed: {
getStyle() {
const obj = {}
return obj
},
getClass() {
let className = `gi-button-${this.type} gi-button-${this.status} gi-button-${this.size} gi-button-${this.shape} `
if (this.disabled) {
className = className + 'disabled'
}
if (this.loading) {
className = className + 'loading'
}
return className
},
getIconClass() {
return this.loading ? 'gi-icon gi-loading-icon' : this.icon
},
getIconStyle() {
const obj = {}
if (this.$slots.default) {
obj['margin-right'] = 4 + 'px'
}
return obj
}
},
methods: {
handleClick() {
if (this.disabled) return
if (this.loading) return
this.$emit('click')
}
}
}
</script>
<style>
:root {
--gi-color-primary: #409eff;
--gi-color-success: #71c031;
--gi-color-warning: #f2a827;
--gi-color-danger: #d40000;
--gi-color-info: #909399;
--gi-size-mini: 28px;
--gi-size-small: 32px;
--gi-size-medium: 36px;
--gi-size-large: 40px;
}
</style>
<style lang="scss" scoped>
$gi-color-primary: var(--gi-color-primary);
$gi-color-success: var(--gi-color-success);
$gi-color-warning: var(--gi-color-warning);
$gi-color-danger: var(--gi-color-danger);
$gi-color-info: var(--gi-color-info);
@font-face {
font-family: 'gi-icon'; /* Project id 2928171 */
src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALoAAsAAAAABpQAAAKaAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACCcAqBDIE0ATYCJAMICwYABCAFhGcHMRvxBcgOJU2XhIj4AQBAPPw39u2+mVkzzaLRJKGWComN0DyTSR2qh8z5k2ualtUmATNyRKTTb/4LmGaMihUQqoIbym5zwJrdbj7/907/BPrAF0T+bE0aa1ObHliA6QdsD8sSjjp56CmsrsVXJ+AZgXqrkvAPsgoqgMMrRHXAlZA1HqTN8UrJISBVMUVBsVao7ru3iBtQRXrNvwK8CT8f/4SFlKQqs9pOn2TKge1txV6Q2//byd+1z9eDxxKqkLEIKMRle+6YQNQJAvU+oXF0FsHPlcq/7xW7dgn511mNjWAQ0j3JrnKrjQmUeHIJcDaqktTt1HRj0Xb6mrqtrP7q+8XqelkQK423VMRbVDS83fJ/H7D12B6ocHew9yDLLNjM6+hL3xSc5Kx0tiyl7PPns+tbvUqCy23cAFrwOWygEwlfBOOphprYccFM8o1BPRT9TjCY8FQbMcjL5c3+dnYmSgFQseQPwf2f+RsH/+cD7zpu/EgbCvixN7YfLqhYCsj3AVB7Nl/w6yy3ehKLjpNKnawCydKoTEK9naQCrFC7u7H2jlsshVodNxqoMZAiqzVOF34eVRqso1qtTdRbkHm4QQcDgSh1mNZFEFqtIWn2DVmrU7rwt6jS7R3VWv2h3nU0nddgOph0ghHFcihrgEpGr2MdGw31lmGuRoNIVboKE5MSSRgaFFIsZmMdJlNsMNVyYZSykCV6LcwSj2GNRg8NRK/CDA1SUGqICw5m614SxOi1IB2BIRQmB8k0gJQYejqsT6b57yuDcWpoIKQnXZUjTJTQD4UKEtKDzjbreg3cySUmtThhKIoFsQgpaEFZahamoaEHGepnqWAMKohiRMYgTrBNYvuag9a3ar+eKEewHCnsqVnNKz2SK3UcAAAA')
format('woff2');
}
.gi-icon {
font-family: 'gi-icon' !important;
font-size: 14px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.gi-loading-icon:before {
content: '\e6a7';
}
@keyframes turn {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(90deg);
}
50% {
-webkit-transform: rotate(180deg);
}
75% {
-webkit-transform: rotate(270deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
.gi-loading-icon {
animation: turn 1s linear infinite;
}
.gi-button {
display: inline-flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 14px;
padding: 0 15px;
border-radius: 2px;
cursor: pointer;
user-select: none;
box-sizing: border-box;
white-space: nowrap;
position: relative;
overflow: hidden;
// transition: all 0.15s;
&.disabled {
opacity: 0.5;
cursor: not-allowed;
}
&-default {
&.gi-button-primary {
border-color: var(--gi-color-primary);
background: var(--gi-color-primary);
}
&.gi-button-success {
border-color: var(--gi-color-success);
background: var(--gi-color-success);
}
&.gi-button-warning {
border-color: var(--gi-color-warning);
background: var(--gi-color-warning);
}
&.gi-button-danger {
border-color: var(--gi-color-danger);
background: var(--gi-color-danger);
}
&.gi-button-info {
border-color: var(--gi-color-info);
background: var(--gi-color-info);
}
}
&-outline,
&-dashed,
&-text {
&.gi-button-primary {
color: var(--gi-color-primary);
}
&.gi-button-success {
color: var(--gi-color-success);
}
&.gi-button-warning {
color: var(--gi-color-warning);
}
&.gi-button-danger {
color: var(--gi-color-danger);
}
&.gi-button-info {
color: var(--gi-color-info);
}
}
&-outline {
border-width: 1px;
background: none !important;
border-style: solid;
}
&-dashed {
border-width: 1px;
background: none;
border-style: dashed;
}
&-text {
background: none;
}
&-mini {
padding: 0 15px;
height: var(--gi-size-mini);
&.gi-button-circle {
width: var(--gi-size-mini);
}
}
&-small {
padding: 0 20px;
height: var(--gi-size-small);
}
&-medium {
padding: 0 25px;
height: var(--gi-size-medium);
}
&-large {
padding: 0 30px;
height: var(--gi-size-large);
}
&-round {
border-radius: 999px;
}
&-circle {
padding: 0;
border-radius: 50%;
}
}
.gi-button.gi-button-default,
.gi-button.gi-button-default {
&:hover {
&::before {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba($color: #fff, $alpha: 0.1);
}
}
&:active {
&::before {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba($color: #000, $alpha: 0.1);
}
}
}
.gi-button.gi-button-default.disabled,
.gi-button.gi-button-default.loading {
&:hover,
&:active {
&::before {
display: none !important;
}
}
}
.gi-button.gi-button-dashed {
&:hover {
opacity: 0.7;
}
&:active {
&::before {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
opacity: 0.1;
}
}
&.gi-button-primary {
&:active {
&::before {
background: var(--gi-color-primary);
}
}
}
&.gi-button-success {
&:active {
&::before {
background: var(--gi-color-success);
}
}
}
&.gi-button-warning {
&:active {
&::before {
background: var(--gi-color-warning);
}
}
}
&.gi-button-danger {
&:active {
&::before {
background: var(--gi-color-danger);
}
}
}
&.gi-button-info {
&:active {
&::before {
background: var(--gi-color-info);
}
}
}
}
.gi-button.gi-button-dashed.disabled {
&:hover {
opacity: 0.5 !important;
background: inherit;
}
&:active {
&::before {
display: none;
}
}
}
.gi-button.gi-button-dashed.loading {
&:hover {
opacity: 1;
background: inherit;
}
&:active {
&::before {
display: none;
}
}
}
.gi-button.gi-button-outline {
&:hover {
opacity: 0.7;
}
&:active {
opacity: 1;
}
}
.gi-button.gi-button-outline.disabled {
&:hover,
&:active {
opacity: 0.5;
}
}
.gi-button.gi-button-outline.loading {
&:hover,
&:active {
opacity: 1;
}
}
.gi-button.gi-button-text {
&:hover {
opacity: 1;
background: #f2f2f2;
}
&:active {
background: #d2d2d2;
}
&.disabled {
&:hover {
opacity: 0.5;
background: none;
}
}
}
.gi-button.gi-button-text.loading {
&:hover {
background: none;
}
&:active {
background: none;
}
}
</style>
演示效果: