ismail9k / vue3-carousel

Vue 3 carousel component
https://ismail9k.github.io/vue3-carousel/
MIT License
661 stars 164 forks source link

Passing v-model leads to Uncaught error: RangeError: Maximum call stack size exceeded #98

Closed reecehill closed 2 years ago

reecehill commented 2 years ago

Describe the bug In order to set the default currentSlide, I attempt to pass an integer, "slideInView", using v-model into the component.

To Reproduce Steps to reproduce the behavior: <carousel v-model="slideInView" :items-to-show="1.5"><slide v-for="slide in slides" :key="slide.id"><div class="carousel__item">{{ slide.title }}</div></slide>

setup() { const slides = [ { id: 0, title: "Test 1" }, { id: 1, title: "Test 2" }, { id: 2, title: "Test 3" }, ]; return { slides }; },

data() { return { slideInView: Number(0) }; },

Leads to:

Uncaught (in promise) RangeError: Maximum call stack size exceeded at RefImpl.get value [as value] (app.js:24420) at slideTo (app.js:122947) at slideTo (app.js:122953) at slideTo (app.js:122953) at slideTo (app.js:122953) at slideTo (app.js:122953) at slideTo (app.js:122953) at slideTo (app.js:122953) at slideTo (app.js:122953) at slideTo (app.js:122953)

The following line appears to be the issue: if (currentSlide.value === slideIndex || isSliding.value) {

I have noticed that this only works as expected when slideInView is -1.

Expected behavior Default currentSlide is set by padding integer to currentSlide variable.

uke5tar commented 2 years ago

Try and set the modelValue or v-model value after the component has mounted. Then you don't get the maximum call stack size exceed error.

Working example code:

<template>
  <carousel
    wrap-around
    v-model="initialSlide">
    <slide v-for="slide in 10" :key="slide">
      {{ slide }}
    </slide>

    <template #addons="{ currentSlide, slidesCount }">
      <Navigation />

      <div>
        {{ currentSlide + 1 }} / {{ slidesCount }}
      </div>
    </template>
  </carousel>
</template>

<script>
import { ref, onMounted } from 'vue';
import { Carousel, Slide, Navigation } from 'vue3-carousel';
import 'vue3-carousel/dist/carousel.css';

export default {
  name: 'Carousel',
  components: {
    Carousel,
    Slide,
    Navigation,
  },
  setup() {
    const initialSlide = ref(undefined);

    onMounted(() => {
      initialSlide.value = 0;
    });

    return {
      initialSlide,
    };
  },
};
</script>
reecehill commented 2 years ago

Try and set the modelValue or v-model value after the component has mounted. Then you don't get the maximum call stack size exceed error.

Working example code:

<template>
  <carousel
    wrap-around
    v-model="initialSlide">
    <slide v-for="slide in 10" :key="slide">
      {{ slide }}
    </slide>

    <template #addons="{ currentSlide, slidesCount }">
      <Navigation />

      <div>
        {{ currentSlide + 1 }} / {{ slidesCount }}
      </div>
    </template>
  </carousel>
</template>

<script>
import { ref, onMounted } from 'vue';
import { Carousel, Slide, Navigation } from 'vue3-carousel';
import 'vue3-carousel/dist/carousel.css';

export default {
  name: 'Carousel',
  components: {
    Carousel,
    Slide,
    Navigation,
  },
  setup() {
    const initialSlide = ref(undefined);

    onMounted(() => {
      initialSlide.value = 0;
    });

    return {
      initialSlide,
    };
  },
};
</script>

Can confirm this works. Brilliant - thank you!

YuryVegero commented 2 years ago

Does not work for me, still seeing the "Maximum call stack size exceeded" error. Here is my code:

<template>
  <carousel v-model="initialSlide">
    <slide v-for="(type, index) in types" :key="index">
      abc
    </slide>
    <template #addons>
      <Navigation />
    </template>
  </carousel>
</template>

<script>
import { onMounted, ref } from 'vue';
import { Carousel, Slide } from 'vue3-carousel';

export default {
  name: 'Types',
  components: {
    Carousel,
    Slide,
  },
  props: {
    types: {
      type: Array,
      required: true,
    },
  },
  setup() {
    const initialSlide = ref(undefined);

    onMounted(() => {
      initialSlide.value = 0;
    });

    return { initialSlide };
  },
};
</script>
uke5tar commented 2 years ago

I can see a few errors in your code:

If that still errors I would recommend you to copy my version since it is working and modify it step by step

YuryVegero commented 2 years ago

I can see a few errors in your code:

  • you don't pass the prop wrap-around to the carousel component in your template
  • you don't import Navigation and define it at components but you use it in your template

If that still errors I would recommend you to copy my version since it is working and modify it step by step

@uke5tar thank you for fast response and pointing to my mistakes. I figured out that the problem in my example is caused by empty types array, which should be set dynamically later in time after fetch completes. The solution in my case is not to render the entire component with v-if when types is empty.

github-actions[bot] commented 2 years ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 2 years ago

This issue was closed because it has been inactive for 14 days since being marked as stale.

github-actions[bot] commented 2 years ago

This issue was closed because it has been inactive for 14 days since being marked as stale.