index.vue 3.21 KB
<template>
  <button class="zui-button" :class="classRender" :style="styleRender" v-on="bindEvents">
    <slot></slot>
  </button>
</template>

<script>
import color from 'color';

export default {
  name: 'Button',
  props: {
    type: {
      type: String,
      default: 'default',
    },
    size: {
      type: String,
      default: 'md',
    },
    block: {
      type: Boolean,
      default: false,
    },
    round: Boolean,
    square: Boolean,
    disabled: Boolean,
    theme: String,
    color: String,
    hoverClass: {
      type: String,
      default: 'button-hover',
    },
    hoverStartTime: {
      type: Number,
      default: 0,
    },
    hoverStayTime: {
      type: Number,
      default: 70,
    },
  },
  data() {
    return {
      active: false,
    };
  },
  computed: {
    classRender() {
      return {
        [this.size]: true,
        [this.type]: true,
        [this.theme]: !!this.theme,
        [this.hoverClass]: this.active,
        disabled: this.disabled,
        block: this.block,
        round: this.round,
        square: this.square,
        custom: !!this.color,
      };
    },
    styleRender() {
      if (this.color) {
        if (this.type === 'primary') {
          return {
            backgroundColor: this.active ? color(this.color).lighten(0.2) : this.color,
            borderColor: this.active ? color(this.color).lighten(0.2) : this.color,
          };
        } else if (this.type === 'secondary') {
          return {
            backgroundColor: this.active ? color(this.color).lightness(90) : color(this.color).lightness(95),
            color: this.color,
          };
        } else if (this.type === 'plain') {
          return {
            borderColor: this.color,
            color: this.color,
            backgroundColor: this.active ? color(this.color).lightness(90) : color(this.color).lightness(95),
          };
        } else if (this.type === 'ghost') {
          return {
            borderColor: this.color,
            color: this.color,
            backgroundColor: this.active ? color(this.color).lightness(95) : undefined,
          };
        } else {
          return {
            color: this.active ? color(this.color).lighten(0.2) : this.color,
          };
        }
      }
      return {};
    },
    bindEvents() {
      const events = this.$listeners || {};
      const activeEvents = ['mousedown', 'touchstart'];
      const deactiveEvents = ['mouseup', 'mousemove', 'touchend', 'touchmove'];
      let safeEvents = { ...events };
      activeEvents.forEach(key => {
        safeEvents[key] = e => {
          const originEvent = events[key];
          originEvent && originEvent(e);
          if (this.hoverStartTime) {
            setTimeout(() => {
              this.active = true;
            }, this.hoverStartTime);
          } else {
            this.active = true;
          }
        };
      });
      deactiveEvents.forEach(key => {
        safeEvents[key] = e => {
          const originEvent = events[key];
          originEvent && originEvent(e);
          setTimeout(() => {
            this.active = false;
          }, this.hoverStayTime);
        };
      });
      return safeEvents;
    },
  },
};
</script>

<style lang="scss">
@import './index.scss';
</style>