|
|
@@ -1,35 +1,56 @@
|
|
|
<template>
|
|
|
- <section class="mb-tabs-container">
|
|
|
- <section class="mb-tabs">
|
|
|
- <div v-for="(tab, index) in productTabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
|
|
- @click="activeTab = index">
|
|
|
- {{ tab.name }}
|
|
|
+ <section class="mb-product-section">
|
|
|
+ <!-- tabs 盖在视频下半部分 -->
|
|
|
+ <section class="mb-tabs-wrapper">
|
|
|
+ <section class="mb-tabs">
|
|
|
+ <div v-for="(tab, index) in productTabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
|
|
+ @click="activeTab = index">
|
|
|
+ {{ tab.name }}
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+ </section>
|
|
|
+ <!-- cards 正常向下排列 -->
|
|
|
+ <section class="mb-cards" :class="{ 'is-multi': isMultiLayout }">
|
|
|
+ <div v-for="(card, index) in displayCards" :key="index" class="mb-card">
|
|
|
+ <h3 class="card-title">{{ card.title }}</h3>
|
|
|
+ <p class="card-description">{{ card.description }}</p>
|
|
|
+ <div v-if="card.features?.length" class="card-features">
|
|
|
+ <span v-for="(feature, idx) in card.features" :key="idx" class="feature-tag">{{ feature }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="card-actions">
|
|
|
+ <button class="btn-primary" type="button">更多详情</button>
|
|
|
+ <button class="btn-secondary" type="button">0元体验</button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <!-- <van-tabs v-model:active="activeTab">
|
|
|
- <van-tab v-for="(tab, index) in productTabs" :title="tab.name">
|
|
|
- </van-tab>
|
|
|
- </van-tabs> -->
|
|
|
</section>
|
|
|
</section>
|
|
|
</template>
|
|
|
+
|
|
|
<script setup>
|
|
|
-import { productTabs } from '~/utils/product';
|
|
|
+import { ref, computed } from 'vue'
|
|
|
+import { productTabs } from '~/utils/product'
|
|
|
|
|
|
const activeTab = ref(0)
|
|
|
|
|
|
-
|
|
|
const currentTabData = computed(() => productTabs[activeTab.value])
|
|
|
-
|
|
|
-
|
|
|
+const displayCards = computed(() => {
|
|
|
+ const cards = currentTabData.value?.cards ?? []
|
|
|
+ return cards
|
|
|
+})
|
|
|
+const isMultiLayout = computed(() => currentTabData.value?.layout === 'multi')
|
|
|
</script>
|
|
|
+
|
|
|
<style lang="scss" scoped>
|
|
|
-.mb-tabs-container {
|
|
|
- position: absolute;
|
|
|
+.mb-product-section {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.mb-tabs-wrapper {
|
|
|
+ position: relative;
|
|
|
width: 100%;
|
|
|
- left: 0;
|
|
|
- top: 58%;
|
|
|
- transform: translateY(-50%);
|
|
|
- z-index: 2;
|
|
|
+ z-index: 3;
|
|
|
+ padding: 0 6px;
|
|
|
+ box-sizing: border-box;
|
|
|
}
|
|
|
|
|
|
.mb-tabs {
|
|
|
@@ -42,13 +63,11 @@ const currentTabData = computed(() => productTabs[activeTab.value])
|
|
|
backdrop-filter: blur(20px);
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- gap: 8px;
|
|
|
padding: 0 12px;
|
|
|
overflow-x: auto;
|
|
|
scroll-behavior: smooth;
|
|
|
-webkit-overflow-scrolling: touch;
|
|
|
|
|
|
- /* 隐藏滚动条 */
|
|
|
scrollbar-width: none;
|
|
|
-ms-overflow-style: none;
|
|
|
|
|
|
@@ -58,10 +77,10 @@ const currentTabData = computed(() => productTabs[activeTab.value])
|
|
|
|
|
|
.tab-item {
|
|
|
flex-shrink: 0;
|
|
|
- font-size: 14px;
|
|
|
font-weight: 400;
|
|
|
- line-height: 1;
|
|
|
color: #ffffff;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 16px;
|
|
|
cursor: pointer;
|
|
|
white-space: nowrap;
|
|
|
transition: color 0.3s ease, background 0.3s ease, transform 0.3s ease;
|
|
|
@@ -85,7 +104,122 @@ const currentTabData = computed(() => productTabs[activeTab.value])
|
|
|
transform: translateY(-1px);
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+.mb-cards {
|
|
|
+ width: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
+ margin-top: 20px;
|
|
|
+ padding: 0 10px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.mb-cards.is-multi {
|
|
|
+ flex-direction: row;
|
|
|
+ overflow-x: auto;
|
|
|
+ scroll-snap-type: x mandatory;
|
|
|
+ scroll-padding: 10px;
|
|
|
+ scroll-behavior: smooth;
|
|
|
+ -webkit-overflow-scrolling: touch;
|
|
|
+ scrollbar-width: none;
|
|
|
+ -ms-overflow-style: none;
|
|
|
+
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.mb-card {
|
|
|
+ width: 100%;
|
|
|
+ border-radius: 20px;
|
|
|
+ border: 1px solid rgba(198, 186, 255, 0.30);
|
|
|
+ background: linear-gradient(177deg, rgba(165, 101, 255, 0.25) -20.47%, rgba(3, 0, 20, 0.25) 134.25%);
|
|
|
+ backdrop-filter: blur(20px);
|
|
|
+ padding: 18px 16px 16px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ min-height: 290px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.mb-cards.is-multi .mb-card {
|
|
|
+ flex: 0 0 96%;
|
|
|
+ scroll-snap-align: center;
|
|
|
+}
|
|
|
|
|
|
+.card-title {
|
|
|
+ margin: 0;
|
|
|
+ text-align: center;
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 18px;
|
|
|
+}
|
|
|
|
|
|
+.card-description {
|
|
|
+ margin: 12px 0 0;
|
|
|
+ color: rgba(255, 255, 255, 0.65);
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 18px;
|
|
|
+ display: -webkit-box;
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+ -webkit-line-clamp: 6;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.card-features {
|
|
|
+ margin-top: 12px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.feature-tag {
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 12px;
|
|
|
+ color: #9b71ff;
|
|
|
+}
|
|
|
+
|
|
|
+.card-actions {
|
|
|
+ margin-top: auto;
|
|
|
+ padding-top: 14px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-primary {
|
|
|
+ display: flex;
|
|
|
+ width: 72px;
|
|
|
+ height: 20px;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+ border-radius: 4px;
|
|
|
+ background: linear-gradient(117deg, #A39DFF -41.28%, #7D46FF 60.31%);
|
|
|
+ color: #FFF;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ padding: 2px 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-secondary {
|
|
|
+ display: flex;
|
|
|
+ width: 72px;
|
|
|
+ height: 20px;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+ border-radius: 4px;
|
|
|
+ background: rgba(255, 255, 255, 0.20);
|
|
|
+ backdrop-filter: blur(2px);
|
|
|
+ color: #FFF;
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: 400;
|
|
|
+ padding: 2px 6px;
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|