index.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <template>
  2. <view :class="classes" :style="getStyle" @click="handleClick">
  3. <view class="nut-button__warp">
  4. <nut-icon class="nut-icon-loading" v-if="loading"></nut-icon>
  5. <nut-icon
  6. v-if="icon && !loading"
  7. :name="icon"
  8. :class-prefix="iconClassPrefix"
  9. :font-class-name="iconFontClassName"
  10. ></nut-icon>
  11. <view :class="{ text: icon || loading }" v-if="$slots.default">
  12. <slot></slot>
  13. </view>
  14. </view>
  15. </view>
  16. </template>
  17. <script lang="ts">
  18. import { PropType, CSSProperties, toRefs, computed } from 'vue';
  19. import { createComponent } from '@/packages/utils/create';
  20. import Icon from '../icon/index.vue';
  21. const { componentName, create } = createComponent('button');
  22. export type ButtonType = 'default' | 'primary' | 'info' | 'success' | 'warning' | 'danger';
  23. export type ButtonSize = 'large' | 'normal' | 'small' | 'mini';
  24. export type ButtonShape = 'square' | 'round';
  25. export default create({
  26. components: {
  27. [Icon.name]: Icon
  28. },
  29. props: {
  30. color: String,
  31. shape: {
  32. type: String as PropType<ButtonShape>,
  33. default: 'round'
  34. },
  35. plain: {
  36. type: Boolean,
  37. default: false
  38. },
  39. loading: {
  40. type: Boolean,
  41. default: false
  42. },
  43. disabled: {
  44. type: Boolean,
  45. default: false
  46. },
  47. type: {
  48. type: String as PropType<ButtonType>,
  49. default: 'default'
  50. },
  51. size: {
  52. type: String as PropType<ButtonSize>,
  53. default: 'normal'
  54. },
  55. block: {
  56. type: Boolean,
  57. default: false
  58. },
  59. icon: {
  60. type: String,
  61. default: ''
  62. },
  63. iconClassPrefix: {
  64. type: String,
  65. default: 'nut-icon'
  66. },
  67. iconFontClassName: {
  68. type: String,
  69. default: 'nutui-iconfont'
  70. }
  71. },
  72. emits: ['click'],
  73. setup(props, { emit, slots }) {
  74. const { type, size, shape, disabled, loading, color, plain, block } = toRefs(props);
  75. const handleClick = (event: MouseEvent) => {
  76. if (!loading.value && !disabled.value) {
  77. emit('click', event);
  78. }
  79. };
  80. const classes = computed(() => {
  81. const prefixCls = componentName;
  82. return {
  83. [prefixCls]: true,
  84. [`${prefixCls}--${type.value}`]: type.value,
  85. [`${prefixCls}--${size.value}`]: size.value,
  86. [`${prefixCls}--${shape.value}`]: shape.value,
  87. [`${prefixCls}--plain`]: plain.value,
  88. [`${prefixCls}--block`]: block.value,
  89. [`${prefixCls}--disabled`]: disabled.value,
  90. [`${prefixCls}--loading`]: loading.value
  91. };
  92. });
  93. const getStyle = computed(() => {
  94. const style: CSSProperties = {};
  95. if (color?.value) {
  96. if (plain.value) {
  97. style.color = color.value;
  98. style.background = '#fff';
  99. if (!color.value?.includes('gradient')) {
  100. style.borderColor = color.value;
  101. }
  102. } else {
  103. style.color = '#fff';
  104. style.background = color.value;
  105. }
  106. }
  107. return style;
  108. });
  109. return {
  110. handleClick,
  111. classes,
  112. getStyle
  113. };
  114. }
  115. });
  116. </script>