Tabs.vue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <template>
  2. <div class="tabs"
  3. :class="{
  4. 'card': card,
  5. 'space-around': spaceAround,
  6. 'space-between': spaceBetween,
  7. }"
  8. :style="tabsStyle || {}"
  9. >
  10. <div
  11. class="tab"
  12. :class="{ 'active': tab.key === value }"
  13. v-for="tab in tabs"
  14. :key="tab.key"
  15. :style="{
  16. ...(tabStyle || {}),
  17. '--color': tab.color,
  18. }"
  19. @click="emit('update:value', tab.key)"
  20. >{{tab.label}}</div>
  21. </div>
  22. </template>
  23. <script lang="ts" setup>
  24. import { type CSSProperties } from 'vue'
  25. interface TabItem {
  26. key: string
  27. label: string
  28. color?: string
  29. }
  30. withDefaults(defineProps<{
  31. value: string
  32. tabs: TabItem[]
  33. card?: boolean
  34. tabsStyle?: CSSProperties
  35. tabStyle?: CSSProperties
  36. spaceAround?: boolean
  37. spaceBetween?: boolean
  38. }>(), {
  39. card: false,
  40. spaceAround: false,
  41. spaceBetween: false,
  42. })
  43. const emit = defineEmits<{
  44. (event: 'update:value', payload: string): void
  45. }>()
  46. </script>
  47. <style lang="scss" scoped>
  48. .tabs {
  49. display: flex;
  50. user-select: none;
  51. line-height: 1;
  52. &:not(.card) {
  53. font-size: 13px;
  54. align-items: center;
  55. justify-content: flex-start;
  56. border-bottom: 1px solid $borderColor;
  57. &.space-around {
  58. justify-content: space-around;
  59. }
  60. &.space-between {
  61. justify-content: space-between;
  62. }
  63. .tab {
  64. text-align: center;
  65. border-bottom: 2px solid transparent;
  66. padding: 8px 10px;
  67. cursor: pointer;
  68. &.active {
  69. border-bottom: 2px solid var(--color, $themeColor);
  70. }
  71. }
  72. }
  73. &.card {
  74. height: 40px;
  75. font-size: 12px;
  76. flex-shrink: 0;
  77. .tab {
  78. flex: 1;
  79. display: flex;
  80. justify-content: center;
  81. align-items: center;
  82. background-color: $lightGray;
  83. border-bottom: 1px solid $borderColor;
  84. cursor: pointer;
  85. &.active {
  86. background-color: transparent;
  87. border-bottom-color: transparent;
  88. }
  89. & + .tab {
  90. border-left: 1px solid $borderColor;
  91. }
  92. }
  93. }
  94. }
  95. </style>