hookehuyr

feat(SummerCampCard): 添加轮播功能并更新数据传递方式

为 SummerCampCard 组件添加 Swiper 轮播功能,支持多张图片切换。同时,将静态数据改为通过 props 传递,提高组件的灵活性和复用性。
......@@ -10,6 +10,7 @@
"dependencies": {
"@vant/use": "^1.6.0",
"dayjs": "^1.11.13",
"swiper": "^11.2.6",
"vant": "^4.9.18",
"vconsole": "^3.15.1",
"vue": "^3.5.13",
......@@ -3342,6 +3343,24 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/swiper": {
"version": "11.2.6",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.6.tgz",
"integrity": "sha512-8aXpYKtjy3DjcbzZfz+/OX/GhcU5h+looA6PbAzHMZT6ESSycSp9nAjPCenczgJyslV+rUGse64LMGpWE3PX9Q==",
"funding": [
{
"type": "patreon",
"url": "https://www.patreon.com/swiperjs"
},
{
"type": "open_collective",
"url": "http://opencollective.com/swiper"
}
],
"engines": {
"node": ">= 4.7.0"
}
},
"node_modules/tailwindcss": {
"version": "3.4.17",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
......
......@@ -11,6 +11,7 @@
"dependencies": {
"@vant/use": "^1.6.0",
"dayjs": "^1.11.13",
"swiper": "^11.2.6",
"vant": "^4.9.18",
"vconsole": "^3.15.1",
"vue": "^3.5.13",
......
<template>
<div class="relative overflow-hidden rounded-b-3xl shadow-lg">
<!-- Background image with overlay -->
<div
class="absolute inset-0 z-0 bg-cover bg-center"
:style="{
backgroundImage: `url('https://cdn.ipadbiz.cn/mlaj/images/summer-camp.jpg')`,
filter: 'brightness(0.4)'
}"
></div>
<div class="swiper-container relative" ref="swiperRef">
<div class="swiper-wrapper">
<div v-for="(item, index) in items" :key="index" class="swiper-slide">
<!-- Background image with overlay -->
<div
class="absolute inset-0 z-0 bg-cover bg-center"
:style="{
backgroundImage: `url(${item.imageUrl || 'https://cdn.ipadbiz.cn/mlaj/images/summer-camp.jpg'})`,
filter: 'brightness(0.4)'
}"
></div>
<!-- Gradient overlay -->
<div class="absolute inset-0 z-1 bg-gradient-to-b from-red-500/70 to-red-600/90"></div>
<!-- Gradient overlay -->
<div class="absolute inset-0 z-1 bg-gradient-to-b from-red-500/70 to-red-600/90"></div>
<!-- Content -->
<div class="relative z-10 p-4">
<div class="bg-white/10 backdrop-blur-sm rounded-lg p-3 mb-3 inline-block">
<div class="text-white font-semibold">{{ badge }}</div>
</div>
<!-- Content -->
<div class="relative z-10 p-4">
<div class="bg-white/10 backdrop-blur-sm rounded-lg p-3 mb-3 inline-block">
<div class="text-white font-semibold">{{ item.badge }}</div>
</div>
<h1 class="text-2xl text-white font-bold mb-1">{{ title }}</h1>
<h2 class="text-lg text-white/90">{{ subtitle }}</h2>
<h1 class="text-2xl text-white font-bold mb-1">{{ item.title }}</h1>
<h2 class="text-lg text-white/90">{{ item.subtitle }}</h2>
<div class="mt-4 flex justify-between items-center">
<div class="text-orange-300 font-bold text-2xl">{{ price }}</div>
<div class="bg-orange-500/30 text-orange-100 text-xs px-3 py-1 rounded-full">{{ discount }}</div>
</div>
<div class="mt-4 flex justify-between items-center">
<div class="text-orange-300 font-bold text-2xl">{{ item.price }}</div>
<div class="bg-orange-500/30 text-orange-100 text-xs px-3 py-1 rounded-full">{{ item.discount }}</div>
</div>
<div class="flex justify-between text-xs text-white/80 mt-3">
<div>已更新{{ episodes }}期</div>
<div>{{ subscribers }}人订阅</div>
<div class="flex justify-between text-xs text-white/80 mt-3">
<div>已更新{{ item.episodes }}期</div>
<div>{{ item.subscribers }}人订阅</div>
</div>
</div>
</div>
</div>
<!-- Pagination -->
<div class="swiper-pagination"></div>
</div>
</div>
</template>
<script setup>
import { defineProps } from 'vue'
import { defineProps, onMounted, ref } from 'vue'
import Swiper from 'swiper'
import { Pagination } from 'swiper/modules'
import 'swiper/css'
import 'swiper/css/pagination'
defineProps({
title: {
type: String,
default: '大国少年-世界正东方'
},
subtitle: {
type: String,
default: '亲子夏令营'
},
badge: {
type: String,
default: '亲子夏令营'
},
price: {
type: String,
default: '¥1280'
},
discount: {
type: String,
default: '限时优惠'
},
episodes: {
type: Number,
default: 16
},
subscribers: {
type: Number,
default: 1140
const props = defineProps({
items: {
type: Array,
default: () => [{
title: '大国少年-世界正东方',
subtitle: '亲子夏令营',
badge: '亲子夏令营',
price: '¥1280',
discount: '限时优惠',
episodes: 16,
subscribers: 1140,
imageUrl: 'https://cdn.ipadbiz.cn/mlaj/images/summer-camp.jpg'
}]
}
})
const swiperRef = ref(null)
onMounted(() => {
new Swiper(swiperRef.value, {
modules: [Pagination],
pagination: {
el: '.swiper-pagination',
clickable: true
},
loop: true
})
})
</script>
<style scoped>
.swiper-container {
width: 100%;
height: 100%;
}
.swiper-slide {
height: auto;
}
.swiper-pagination {
bottom: 10px !important;
}
.swiper-pagination-bullet {
background: white !important;
opacity: 0.5;
}
.swiper-pagination-bullet-active {
opacity: 1;
}
</style>
......
<!--
* @Date: 2025-03-20 19:55:21
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-03-20 23:13:20
* @LastEditTime: 2025-03-21 09:35:57
* @FilePath: /mlaj/src/views/HomePage.vue
* @Description: 文件描述
-->
......@@ -25,13 +25,13 @@
<p class="text-sm text-gray-500">{{ formatToday() }}</p>
</div>
</div>
<div class="flex items-center text-sm">
<!-- <div class="flex items-center text-sm">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<span class="ml-1 font-medium">23°C</span>
<span class="ml-1 text-gray-500">晴朗</span>
</div>
</div> -->
</div>
<!-- User Stats -->
......@@ -40,14 +40,14 @@
<div class="text-lg font-bold">3</div>
<div class="text-xs text-gray-500">连续打卡</div>
</div>
<div class="border-r border-gray-200 flex-1">
<div class="border-gray-200 flex-1">
<div class="text-lg font-bold">12</div>
<div class="text-xs text-gray-500">已学课程</div>
</div>
<div class="flex-1">
<!-- <div class="flex-1">
<div class="text-lg font-bold">25</div>
<div class="text-xs text-gray-500">积分</div>
</div>
</div> -->
</div>
</FrostedGlass>
......@@ -127,7 +127,38 @@
<!-- Summer Camp Promotion -->
<div class="px-4 mb-6">
<SummerCampCard />
<SummerCampCard :items="[
{
title: '大国少年-世界正东方',
subtitle: '亲子夏令营',
badge: '亲子夏令营',
price: '¥1280',
discount: '限时优惠',
episodes: 16,
subscribers: 1140,
imageUrl: 'https://cdn.ipadbiz.cn/mlaj/images/summer-camp.jpg'
},
{
title: '暑期特训营',
subtitle: '提升学习能力',
badge: '特训营',
price: '¥1580',
discount: '早鸟优惠',
episodes: 20,
subscribers: 980,
imageUrl: 'https://cdn.ipadbiz.cn/mlaj/images/summer-camp-2.jpg'
},
{
title: '艺术创想营',
subtitle: '激发创造力',
badge: '艺术营',
price: '¥1380',
discount: '新课优惠',
episodes: 12,
subscribers: 760,
imageUrl: 'https://cdn.ipadbiz.cn/mlaj/images/summer-camp-3.jpg'
}
]" />
</div>
<!-- Featured Courses Carousel -->
......