Search code examples
javascriptvue.jsvuejs3carouselembla-carousel

Embla Carousel Vue3 scrollNext Event


I'm hoping to get Embla Carousel setup in my Vue project, but I can't get the scrollNext function to work.

Here's where I am:

<script setup>
import { onMounted } from 'vue'
import emblaCarouselVue from 'embla-carousel-vue'
import Autoplay from 'embla-carousel-autoplay'

const [emblaRef, emblaApi] = emblaCarouselVue({ loop: true }, [Autoplay()])

function prevSlide () {
  emblaApi.value.scrollPrev()
}

function nextSlide () {
  emblaApi.value.scrollNext()
} 
</script>
<template>
  <div class="embla" ref="emblaRef">
    <div class="embla__viewport">
      <div class="embla__container">
        <div class="embla__slide">
          <div class="embla__parallax">
            <div class="embla__parallax__layer">
              <img
                class="embla__slide__img embla__parallax__img"
                src="https://picsum.photos/1000/350?v=1"
                alt="Your alt text"
              />
            </div>
          </div>
        </div>
...
    <button @click="prevSlide">Prev</button>
    <button @click="nextSlide">Next</button>

You can view the project using this codesandbox. The ideal solution would allow me to leverage the parallax effect as seen in the embla docs.


Solution

  • Embla expects the first child element of the root to hold the slides. Since you added div.embla__viewport between the root and the container, you have to tell Embla about it via the container option:

    const [emblaRef, emblaApi] = emblaCarouselVue({
      loop: true,
      container: '.embla__container', // <----- use custom container
    }, [Autoplay()]);
    

    I think you could also just move the template ref, Embla does not seem to use the classes internally.


    The parallax effect is not a builtin, you have to use the code and styles from the example (see css/embla.css and js/EmblaCarouselTweenParallax.js in their sandbox).


    Here is the updated stackblitz with these changes:

    • added the container option as described above
    • removed css in Carousel.vue
    • added file embla.css (copied from example sandbox)
    • added file composables/emblaParallax.js (copied from example sandbox)
      • wrapped init function so parallax is cleaned up on unmount
    • called useEmblaParallax() in Carousel.vue

    Let me know, does that work for you?