Vue-carousel: Feature: Fully customized pagination and navigation

Created on 8 Oct 2017  路  12Comments  路  Source: SSENSE/vue-carousel

Hi,

Could you please add named slots for pagination and navigation, so that it would be possible to entirely customize either?

Thanks.

feature good first issue help wanted

Most helpful comment

Actually, you can simply create a customized navigation by making use of vue's ref property.

import { Carousel, Slide } from 'vue-carousel';

new Vue({
  el: '#app',
  template: `
    <carousel ref="carousel">
           <slide></slide>
    </carousel>
     <a @click.prevent="prevSlide">Prev</a>
     <a @click.prevent="nextSlide">Next</a>
  `,
  methods: {
    nextSlide() {
      this.$refs.carousel.goToPage(this.$refs.carousel.getNextPage());
    },
    prevSlide() {
      this.$refs.carousel.goToPage(this.$refs.carousel.getPreviousPage());
    }
  },
  components: {
      Carousel,
      Slide
  }
})

or a cleaner way would be to implement an event bus and then provide a this.bus.$emit('nextPage') event. @quinnlangille what do you think? I can implement it if this is a feature you would like to have.

All 12 comments

The current possible way for creating custom pagination and navigation is by force calling goToPage() method in Carousel.vue from outside, and by listening to event emitted by that carousel component if you need to update your custom pagination/navigation.

I have done custom arrows like this

:navigationPrevLabel='(back_tick)<img src="/public/images/icons/arrow-left1.png" class="slider-prev">(back_tick)'

:navigationNextLabel='(back_tick)<img src="/public/images/icons/arrow-right1.png" class="slider-next">(back_tick)'

( replace back_tick with backtick duh! )
and then style it in css!

( Optional )
Incase if we want custom next and prev button placed somewhere below the slider and to target the slider, I have written the following

SlideCarousel(value) {
    const carousel = this.$refs['productDetails'][0];
    const currentPage = carousel.currentPage;
    const pageCount = carousel.pageCount;
    if (value == 'prev') {
        currentPage != 0 ? carousel.goToPage(currentPage - 1) : carousel.goToPage(pageCount - 1);
    } else {
        currentPage < pageCount - 1 ? carousel.goToPage(currentPage + 1) : carousel.goToPage(0);
    }
},

and the clicks like this
@click="SlideCarousel('prev')"
@click="SlideCarousel('next')"

and add ref="productDetails" attr to <carousel> tag

This would be an incredibly useful feature. Other sliders use a simple selector option for the next and previous buttons. You can then use any element(s) on the page, not just within the slider, to control it. Otherwise though I think Vue's slots would be an excellent candidate for this feature. This feature would pretty much make me abandon what im using now in favor of this carousel. Cheers.

Actually, you can simply create a customized navigation by making use of vue's ref property.

import { Carousel, Slide } from 'vue-carousel';

new Vue({
  el: '#app',
  template: `
    <carousel ref="carousel">
           <slide></slide>
    </carousel>
     <a @click.prevent="prevSlide">Prev</a>
     <a @click.prevent="nextSlide">Next</a>
  `,
  methods: {
    nextSlide() {
      this.$refs.carousel.goToPage(this.$refs.carousel.getNextPage());
    },
    prevSlide() {
      this.$refs.carousel.goToPage(this.$refs.carousel.getPreviousPage());
    }
  },
  components: {
      Carousel,
      Slide
  }
})

or a cleaner way would be to implement an event bus and then provide a this.bus.$emit('nextPage') event. @quinnlangille what do you think? I can implement it if this is a feature you would like to have.

Would be great @Orlandster1998! Feel free to open a PR and I'll review when it's up :~)

Maybe it's better to use named slots? One for next, one for prev. Another one for pagination.

Agree with @acupofspirt , I think it could be

<slot
  name="navigation"
  goToNextSlide="goToNextSlide"
>
  // navigation here
</slot>

// and use `goToNextSlide` in this way
<template
  name="navigation"
  scope="{ goToNextSlide }"
>
  <button @click="goToNextSlide()">Click here to go to next slide</button>
</template>

This way could avoid using $refs and use the method in safe way

using the backticks breaks ie11. this worked for me:

navigation-prev-label="<span class='sr-only'>Prev</span>"

and then add the arrow with :after
button.VueCarousel-navigation-button:after { content: '>' }

Actually, you can simply create a customized navigation by making use of vue's ref property.

import { Carousel, Slide } from 'vue-carousel';

new Vue({
  el: '#app',
  template: `
    <carousel ref="carousel">
           <slide></slide>
    </carousel>
     <a @click.prevent="prevSlide">Prev</a>
     <a @click.prevent="nextSlide">Next</a>
  `,
  methods: {
    nextSlide() {
      this.$refs.carousel.goToPage(this.$refs.carousel.getNextPage());
    },
    prevSlide() {
      this.$refs.carousel.goToPage(this.$refs.carousel.getPreviousPage());
    }
  },
  components: {
      Carousel,
      Slide
  }
})

or a cleaner way would be to implement an event bus and then provide a this.bus.$emit('nextPage') event. @quinnlangille what do you think? I can implement it if this is a feature you would like to have.

GREAT JOB BRO :)

Actually, you can simply create a customized navigation by making use of vue's ref property.

import { Carousel, Slide } from 'vue-carousel';

new Vue({
  el: '#app',
  template: `
    <carousel ref="carousel">
           <slide></slide>
    </carousel>
     <a @click.prevent="prevSlide">Prev</a>
     <a @click.prevent="nextSlide">Next</a>
  `,
  methods: {
    nextSlide() {
      this.$refs.carousel.goToPage(this.$refs.carousel.getNextPage());
    },
    prevSlide() {
      this.$refs.carousel.goToPage(this.$refs.carousel.getPreviousPage());
    }
  },
  components: {
      Carousel,
      Slide
  }
})

or a cleaner way would be to implement an event bus and then provide a this.bus.$emit('nextPage') event. @quinnlangille what do you think? I can implement it if this is a feature you would like to have.

named slot would be much more better. no need to add more event listeners

Yeah, I agree with @1yzz. While you can use refs, named slots would be much more idiomatic and easy to use.

I think this will make the code more scalable, because I can use the same code for multiple instances on the same page:

carouselNav($event, direction) {
    const ref = $event.target.closest('[data-ref]').dataset.ref;
    const carousel = this.$refs[ref];

    carousel.advancePage(direction);
}

Add ref and data-ref attributes to carousel: <carousel ref="carousel" data-ref="carousel">

Previous: @click="carouselNav($event, 'backward')"

Next: @click="carouselNav($event, 'forward')"

Et voil脿! ;D

_Note:_ for next, the parameters are optional - just @click="carouselNav" works!

Hope this helps!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

prezmix picture prezmix  路  5Comments

blackforestcode picture blackforestcode  路  4Comments

kenyk7 picture kenyk7  路  4Comments

christophrumpel picture christophrumpel  路  4Comments

ranasl62 picture ranasl62  路  3Comments