一个vue按钮组件

423 阅读1分钟

组件代码:

<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>

演示效果:

ywc5w-7tz3o.gif