Created
November 8, 2023 09:30
-
-
Save geff21st/2413cdbce75fb53a47c51e0c96da0452 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @typedef {import('vue').Ref} Ref | |
* @typedef {import('vue').ComputedRef} ComputedRef | |
* @typedef {import('swiper').Swiper} SwiperType | |
* @typedef {import('swiper/types').SwiperEvents} SwiperEvents | |
* @typedef {import('swiper/types').CSSSelector} CSSSelector | |
* @typedef {import('swiper/types').SwiperOptions} SwiperOptions | |
* @typedef {{ [event in keyof SwiperEvents]?: SwiperEvents[event] }} SwiperEventsList | |
*/ | |
import { computed, onMounted, ref } from 'vue'; | |
import { Swiper } from 'swiper/bundle'; | |
import { Navigation, Pagination } from 'swiper'; | |
import 'swiper/swiper-bundle.min.css'; | |
/** | |
* @param sliderContainer | |
* @param {ComputedRef<SwiperOptions> | null} options | |
* @param {boolean} initOnMount | |
* @returns {{ swiper: Ref<SwiperType>, slideIndex: Ref<number>, init: () => void }} | |
*/ | |
export function useSwiperSlider( | |
sliderContainer, | |
options = null, | |
initOnMount = false, | |
) { | |
const swiper = ref(undefined); | |
const isInitialized = ref(false); | |
const slideIndex = ref(0); | |
const inputEvents = computed(() => { | |
const optionsValue = | |
/** @type SwiperOptions */ | |
options?.value; | |
const optionsEvents = | |
/** @type {SwiperEventsList | undefined} */ | |
optionsValue?.on; | |
return /** @type {SwiperEventsList} */ (optionsEvents || {}); | |
}); | |
const setSlideIndex = (swiper) => { | |
slideIndex.value = swiper.realIndex; | |
}; | |
const handleInitialized = (swiper) => { | |
setSlideIndex(swiper); | |
const inputHandler = inputEvents.value.init; | |
if (inputHandler && typeof inputHandler === 'function') { | |
inputHandler(swiper); | |
} | |
}; | |
const handleSlideChanged = (swiper) => { | |
setSlideIndex(swiper); | |
const inputHandler = inputEvents.value.slideChange; | |
if (inputHandler && typeof inputHandler === 'function') { | |
inputHandler(swiper, slideIndex.value); | |
} | |
}; | |
const swiperOptions = computed(() => ( | |
/** @type SwiperOptions */ { | |
modules: [Navigation, Pagination], | |
navigation: { | |
nextEl: /** @type CSSSelector */ '.swiper-button-next', | |
prevEl: /** @type CSSSelector */ '.swiper-button-prev', | |
}, | |
pagination: { | |
el: /** @type CSSSelector */ '.swiper-pagination', | |
dynamicBullets: true, | |
}, | |
grabCursor: true, | |
...(options ? options.value : null), | |
on: /** @type {SwiperEventsList} */ { | |
...inputEvents.value, | |
init: handleInitialized, | |
slideChange: handleSlideChanged, | |
}, | |
} | |
)); | |
const init = () => { | |
if (isInitialized.value) { | |
return; | |
} | |
isInitialized.value = true; | |
setTimeout(() => { | |
swiper.value = new Swiper(sliderContainer.value, swiperOptions.value); | |
}); | |
}; | |
const destroy = () => { | |
isInitialized.value = false; | |
if (!swiper.value) { | |
return; | |
} | |
setTimeout(() => { | |
swiper.value.destroy(); | |
}); | |
}; | |
if (initOnMount) { | |
onMounted(init); | |
} | |
return { | |
swiper, | |
slideIndex, | |
isInitialized, | |
init, | |
destroy, | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment