index.vue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <template>
  2. <button
  3. class="m-button"
  4. :class="styleClass"
  5. :disabled="disabled"
  6. :round="round"
  7. @click="handleClick">
  8. <i class="iconfont icon-loading" v-if="loading"></i>
  9. <i :class="isIconClass" v-if="leftIcon && !loading"></i>
  10. <span ref="slotRef" :style="slotStyle" :class=" isHaveSlot ? 'noText': '' ">
  11. <slot></slot>
  12. </span>
  13. <i :class="isIconClass" v-if="rightIcon"></i>
  14. </button>
  15. </template>
  16. <script>
  17. export default {
  18. name: "mButton"
  19. };
  20. </script>
  21. <script setup>
  22. import { computed, ref, onMounted } from 'vue-demi';
  23. const emits = defineEmits(['click'])
  24. const props = defineProps({
  25. type: {
  26. type: String,
  27. default: 'default',
  28. validator(value) {
  29. return ['default','primary', 'success', 'info', 'warning', 'danger','text'].indexOf(value) > -1;
  30. }
  31. },
  32. disabled: {
  33. type: Boolean,
  34. default: false
  35. },
  36. round: {
  37. type: Boolean,
  38. default: false
  39. },
  40. circle: {
  41. type: Boolean,
  42. default: false
  43. },
  44. leftIcon: {
  45. type: String,
  46. default: ""
  47. },
  48. rightIcon: {
  49. type: String,
  50. default: ""
  51. },
  52. loading: {
  53. type: Boolean,
  54. default: false
  55. },
  56. size: {
  57. type: String,
  58. default: "default"
  59. }
  60. })
  61. const slotRef = ref(null)
  62. const isHaveSlot = ref(null)
  63. const styleClass = computed(() => {
  64. return {
  65. [`m-button--${props.type}`]: props.type,
  66. 'is-disabled': props.disabled,
  67. 'is-round': props.round,
  68. 'is-circle': props.circle,
  69. [`m-button--${props.size}`]: props.size
  70. }
  71. })
  72. const isIconClass = computed(() => {
  73. return [
  74. 'iconfont',
  75. props.leftIcon || props.rightIcon
  76. ]
  77. })
  78. const slotStyle = computed(() => {
  79. return {
  80. 'margin-left': props.leftIcon ? '4px' : '0',
  81. 'margin-right': props.rightIcon ? '4px' : '0'
  82. }
  83. })
  84. const handleClick = (e) => {
  85. emits('click')
  86. }
  87. onMounted(() => {
  88. if(!slotRef.value.innerText) {
  89. isHaveSlot.value = true
  90. }
  91. })
  92. </script>
  93. <style lang="scss" scoped>
  94. @import '../../styles/components/button.scss';
  95. </style>