提交代码

This commit is contained in:
yiqiuyang
2025-10-15 16:46:35 +08:00
parent 9a01223fc9
commit 502eaff488
36 changed files with 595 additions and 196 deletions

View File

@ -1,12 +1,5 @@
<script setup>
import {
ref,
computed,
watch,
nextTick,
getCurrentInstance,
onUnmounted,
} from 'vue'
import {ref, computed, watch, nextTick, getCurrentInstance, onUnmounted} from 'vue'
/* -------------------- 组件接口定义 -------------------- */
const currentPage = defineModel({type: [Number, String], default: 1})
@ -26,7 +19,7 @@ const props = defineProps({
sourceGap: {type: Number, default: 20},
})
const emit = defineEmits(['page-change', 'item-click', 'item-hover'])
const emit = defineEmits(['page-change', 'item-click', 'item-hover', 'title-click'])
/* -------------------- 响应式变量 -------------------- */
const instance = getCurrentInstance()
@ -39,18 +32,18 @@ const itemWidth = computed(() => $fontSize(props.sourceWidth))
const itemHeight = computed(() => $fontSize(props.sourceHeight))
const itemGap = computed(() => $fontSize(props.sourceGap))
const itemTotalWidth = computed(() => itemWidth.value + itemGap.value)
const viewPortWidth = computed(
() =>
props.pageSize * itemWidth.value +
(props.pageSize - 1) * itemGap.value +
'px'
)
const trackWidth = computed(
() => props.data.length * itemTotalWidth.value - itemGap.value + 'px'
)
const viewPortWidth = computed(() => props.pageSize * itemWidth.value + (props.pageSize - 1) * itemGap.value + 'px')
const trackWidth = computed(() => props.data.length * itemTotalWidth.value - itemGap.value + 'px')
const totalPages = computed(() => props.data.length - props.pageSize + 1)
/* -------------------- 方法 -------------------- */
/**
* 标题点击事件
*/
const clickTitle = () => {
emit('title-click')
}
/**
* 执行平移动画
* @param {number} page - 目标页码
@ -58,9 +51,7 @@ const totalPages = computed(() => props.data.length - props.pageSize + 1)
const translate = (page) => {
if (!trackRef.value) return
trackRef.value.style.transition = `transform ${props.transitionDuration}ms ease`
trackRef.value.style.transform = `translateX(-${
itemTotalWidth.value * (page - 1)
}px)`
trackRef.value.style.transform = `translateX(-${itemTotalWidth.value * (page - 1)}px)`
}
/**
@ -75,8 +66,7 @@ const goToPage = (page) => {
* 切换到下一页,循环播放
*/
const nextPage = () => {
const nextPage =
currentPage.value < totalPages.value ? currentPage.value + 1 : 1
const nextPage = currentPage.value < totalPages.value ? currentPage.value + 1 : 1
goToPage(nextPage)
}
@ -84,8 +74,7 @@ const nextPage = () => {
* 切换到上一页,循环播放
*/
const prevPage = () => {
const prevPage =
currentPage.value > 1 ? currentPage.value - 1 : totalPages.value
const prevPage = currentPage.value > 1 ? currentPage.value - 1 : totalPages.value
goToPage(prevPage)
}
@ -175,7 +164,10 @@ onUnmounted(stopAutoPlay)
<template>
<section :id="id" class="generic-carousel">
<!-- 标题 -->
<h2 v-if="title" class="carousel-title">{{ title }}</h2>
<slot name="title">
<h2 v-if="title" class="carousel-title" @click="clickTitle">{{ title }}</h2>
</slot>
<!-- <h2 v-if="title" class="carousel-title">{{ title }}</h2> -->
<!-- 分页指示器 -->
<div v-if="showDot" class="carousel-pagination">
@ -189,16 +181,9 @@ onUnmounted(stopAutoPlay)
</div>
<!-- 导航按钮 -->
<div
v-if="showPagination && totalPages > 1"
class="carousel-navigation flex j-s"
>
<button class="nav-btn prev-btn" @click="prevPage" aria-label="上一页">
&lt;
</button>
<button class="nav-btn next-btn" @click="nextPage" aria-label="下一页">
&gt;
</button>
<div v-if="showPagination && totalPages > 1" class="carousel-navigation flex j-s">
<button class="nav-btn prev-btn" @click="prevPage" aria-label="上一页">&lt;</button>
<button class="nav-btn next-btn" @click="nextPage" aria-label="下一页">&gt;</button>
</div>
<!-- 轮播内容区域 -->
@ -224,11 +209,7 @@ onUnmounted(stopAutoPlay)
@mouseenter="handleItemHover(item, index)"
@mouseleave="handleItemHoverLeave(item, index)"
>
<slot
:item="item"
:index="index"
:isActive="currentPage === Math.ceil((index + 1) / pageSize)"
/>
<slot :item="item" :index="index" :isActive="currentPage === Math.ceil((index + 1) / pageSize)" />
</div>
</div>
</div>
@ -247,6 +228,10 @@ onUnmounted(stopAutoPlay)
font-weight: 600;
font-size: 24px;
color: #333333;
&:hover {
cursor: pointer;
color: #0389ff;
}
}
.carousel-pagination {
@ -336,5 +321,9 @@ onUnmounted(stopAutoPlay)
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}
}
.item-title {
margin-bottom: 5px;
}
}
</style>