提交代码
This commit is contained in:
@ -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="上一页">
|
||||
<
|
||||
</button>
|
||||
<button class="nav-btn next-btn" @click="nextPage" aria-label="下一页">
|
||||
>
|
||||
</button>
|
||||
<div v-if="showPagination && totalPages > 1" class="carousel-navigation flex j-s">
|
||||
<button class="nav-btn prev-btn" @click="prevPage" aria-label="上一页"><</button>
|
||||
<button class="nav-btn next-btn" @click="nextPage" aria-label="下一页">></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>
|
||||
|
||||
Reference in New Issue
Block a user