104 lines
2.4 KiB
Vue
104 lines
2.4 KiB
Vue
<script setup lang="ts">
|
|
import { Splide, SplideTrack } from '@splidejs/vue-splide'
|
|
import type { Splide as SplideType, ResponsiveOptions } from '@splidejs/splide'
|
|
import type { PageDataResourceGroups } from '#layers/types/api/pageData'
|
|
|
|
interface Props {
|
|
type?: ResponsiveOptions['type']
|
|
slideItemLength?: number
|
|
gap?: number
|
|
autoplay?: boolean
|
|
interval?: number
|
|
perPage?: number
|
|
drag?: boolean
|
|
arrows?: boolean
|
|
arrowsData?: PageDataResourceGroups
|
|
pagination?: boolean
|
|
paginationData?: PageDataResourceGroups
|
|
destroy?: boolean
|
|
breakpoints?: ResponsiveOptions['breakpoints']
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
gap: 0,
|
|
autoplay: false,
|
|
interval: 5000,
|
|
perPage: 1,
|
|
drag: true,
|
|
arrows: true,
|
|
pagination: true,
|
|
destroy: false,
|
|
})
|
|
|
|
const emit = defineEmits(['mounted', 'move'])
|
|
|
|
const splideIndex = defineModel<number>('index', { required: false })
|
|
|
|
const slideType = computed(() => {
|
|
if (props.type) return props.type
|
|
|
|
return (props.slideItemLength ?? 0) > 1 ? 'loop' : 'slide'
|
|
})
|
|
|
|
const options = computed((): ResponsiveOptions => {
|
|
return {
|
|
type: slideType.value,
|
|
autoWidth: true,
|
|
autoHeight: true,
|
|
gap: props.gap,
|
|
perPage: props.perPage,
|
|
speed: 600,
|
|
easing: 'ease-in-out',
|
|
updateOnMove: true,
|
|
autoplay: props.autoplay,
|
|
interval: props.interval,
|
|
drag: props.drag,
|
|
arrows: props.arrows,
|
|
pagination: props.pagination,
|
|
destroy: props.destroy,
|
|
flickPower: 300,
|
|
classes: {
|
|
pagination: 'splide-pagination-bullets',
|
|
page: 'splide-pagination-bullet',
|
|
},
|
|
...(props.breakpoints ? { breakpoints: props.breakpoints } : {}),
|
|
}
|
|
})
|
|
|
|
const handleSplideMounted = (splide: SplideType) => {
|
|
emit('mounted', splide)
|
|
|
|
if (splideIndex.value !== undefined) {
|
|
splideIndex.value = splide.index
|
|
}
|
|
}
|
|
|
|
const handleMove = (
|
|
splide: SplideType,
|
|
newIndex: number,
|
|
oldIndex: number,
|
|
destIndex: number
|
|
) => {
|
|
emit('move', splide, newIndex, oldIndex, destIndex)
|
|
|
|
if (splideIndex.value !== undefined) {
|
|
splideIndex.value = newIndex
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<Splide
|
|
:options="options"
|
|
:has-track="false"
|
|
:style="getPaginationClass(props?.paginationData)"
|
|
@splide:mounted="handleSplideMounted"
|
|
@splide:move="handleMove"
|
|
>
|
|
<SplideTrack>
|
|
<slot />
|
|
</SplideTrack>
|
|
<BlocksSlideArrows v-if="props.arrows" :arrows-data="props.arrowsData" />
|
|
</Splide>
|
|
</template>
|