ProductTabs.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <div class="product-tabs-container">
  3. <section class="product-tabs">
  4. <div v-for="(tab, index) in productTabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
  5. @click="activeTab = index">
  6. {{ tab.name }}
  7. </div>
  8. </section>
  9. <section class="product-cards-wrapper">
  10. <Transition name="fade" mode="out-in">
  11. <component :is="currentLayout" :key="activeTab" :cards="currentTabData.cards" />
  12. </Transition>
  13. </section>
  14. </div>
  15. </template>
  16. <script setup>
  17. import { ref, computed } from 'vue'
  18. import MultiCardLayout from './ProductTabs/MultiCardLayout.vue'
  19. import SingleCardLayout from './ProductTabs/SingleCardLayout.vue'
  20. import { productTabs } from '~/utils/product'
  21. const activeTab = ref(0)
  22. const currentTabData = computed(() => productTabs[activeTab.value])
  23. const currentLayout = computed(() => {
  24. return currentTabData.value.layout === 'multi' ? MultiCardLayout : SingleCardLayout
  25. })
  26. </script>
  27. <style scoped lang="scss">
  28. .product-tabs-container {
  29. position: relative;
  30. width: 100%;
  31. margin-top: 60px;
  32. margin-bottom: 120px;
  33. z-index: 2;
  34. }
  35. .product-tabs {
  36. width: 100%;
  37. max-width: 1200px;
  38. padding: 0 20px;
  39. box-sizing: border-box;
  40. height: 100px;
  41. margin: 0 auto;
  42. border-radius: 150px;
  43. background: linear-gradient(177deg, rgba(165, 101, 255, 0.30) -20.47%, rgba(3, 0, 20, 0.30) 134.25%);
  44. backdrop-filter: blur(20px);
  45. display: flex;
  46. align-items: center;
  47. gap: 22px;
  48. .tab-item {
  49. font-size: 16px;
  50. font-weight: 400;
  51. line-height: 16px;
  52. color: #ffffff;
  53. cursor: pointer;
  54. white-space: nowrap;
  55. transition: color 0.3s ease, background 0.3s ease, transform 0.3s ease;
  56. display: flex;
  57. align-items: center;
  58. justify-content: center;
  59. width: 177px;
  60. height: 60px;
  61. padding: 0;
  62. border-radius: 46.5px;
  63. background: transparent;
  64. &.active {
  65. background: linear-gradient(62.84deg, rgba(130, 77, 255, 1) 0%, rgba(164, 125, 255, 1) 100%);
  66. color: #ffffff;
  67. }
  68. &:hover:not(.active) {
  69. color: #bdbdbd;
  70. transform: translateY(-2px);
  71. }
  72. }
  73. }
  74. .product-cards-wrapper {
  75. position: relative;
  76. width: 80%;
  77. max-width: 1200px;
  78. margin: 10px auto 0;
  79. box-sizing: border-box;
  80. z-index: 1;
  81. backdrop-filter: blur(10px);
  82. }
  83. .product-cards {
  84. width: 100%;
  85. height: 474px;
  86. border-radius: 20px;
  87. background: linear-gradient(177deg, rgba(165, 101, 255, 0.30) -20.47%, rgba(3, 0, 20, 0.30) 134.25%);
  88. }
  89. .fade-enter-active,
  90. .fade-leave-active {
  91. transition: opacity 0.5s ease, transform 0.5s ease;
  92. }
  93. .fade-enter-from {
  94. opacity: 0;
  95. transform: translateY(20px);
  96. }
  97. .fade-leave-to {
  98. opacity: 0;
  99. transform: translateY(-20px);
  100. }
  101. </style>