staskjs/vue-slick

problems with reSlick

Closed this issue ยท 15 comments

I am using v-for loop to render slides and when I add new slide I run reSlick

this.$refs.slick.reSlick()

it works fine on static content with no v-for, for example this works:

        <slick ref="slick" :options="slickOptions">
            <div class="slide">
                <img src="/uploads/2017/10/5/lamborghini-aventador-zaragoza-wide-1_large.jpg" alt="" class="img-responsive" style="width: 100%;">
            </div>
            <div class="slide">
                <img src="/uploads/2017/10/5/lamborghini-aventador-zaragoza-wide-1_large.jpg" alt="" class="img-responsive" style="width: 100%;">
            </div>
        </slick>

I run reSlick on that and it does not mess up the slides, however if I have a v-for where I can dinamically insert slides then I get a problem

example:

template:

        <slick ref="slick" :options="slickOptions">
            <component v-for="slide in slides"
              v-bind:is="slide.type"
              :uniqueId="slide.uniqueId"
              v-bind="slide.settings"
              v-on:remove="removeBlock(slide.uniqueId)"
              :key="slide.uniqueId">
            </component>
        </slick>

watch:

    watch: {
        slides(val) {
            this.reInit()
        }

As soon as I add second slide manually throught user interface of my app, the html code that is output should be two slides, it should output only slide component template:

<div class="slide">
    {{uniqueId}}
    <img style="width: 100%;" class="img-responsive" src="/uploads/2017/10/5/lamborghini-aventador-zaragoza-wide-1_large.jpg" alt="">
</div>

however after reSlick is run, it "swallows" all html code but of the last slide added. So I can't reinitialize slides after i add new slide, all old slides get removed from html and latest one is inserted.
This does not happen if reSlick is not run after I manually add a slide.

Did you try to use Vue.nextTick as in readme?

Im trying to use it with the following code but it removes all the html code created with v-for.

api.get('/profile/vehicles')
          .then(res => {
            this.vehicles = res.data.data;
            this.$nextTick(function () {
              this.$refs.slick.reSlick();
            })
          })

Same problem here...

Hi guys, did someone manage to get this working? Still having the problem too.
I'm doing it this way:

template:

<slick ref="carousel">
  <div v-for="word in words">
     { word }
  </div>
</slick>

script:

<script>
export default {
  data: function () {
    return {
      words: ['a', 'b', 'c']
  },
  mounted: function() {
    setInterval(() => {
      this.words.push('word')
    }, 1000)

    this.$nextTick(function () {
      this.$refs.carousel.reSlick()
    });
  }
}
</script>

And it does not update it. Any idea?

====================
EDIT : I did it !!
Here's my solution (probably not the prettiest but still working) :

<template>
  <slick ref="carousel">
    <div v-for="word in words">
      {{word}}
    </div>
  </slick>
</template>

<script>
import Slick from 'vue-slick';

export default {
  data: function () {
    return {
      words: [
        "a",
        "b",
        "c",
        "d"
      ],
    }
  },
  components: {
    Slick
  },
  mounted: function () {
    setInterval(() => {
      this.words.push('word')
    }, 2000)
  },
  watch: {
    words: function (newWords) {
      let currIndex = this.$refs.carousel.currentSlide()

      this.$refs.carousel.destroy()
      this.$nextTick(() => {
        this.$refs.carousel.create()
        this.$refs.carousel.goTo(currIndex, true)
      })
    }
  }
}
</script>

Basically, the function reSlick is doing Destroy() and Create(), but it is not waiting for the nextTick().

Here, I add a word each 2 seconds and I watch the property "words". On this change, I destroy the current carousel, and create it again after one tick. Obviously the index goes back to 0 so I store it beforehand.

Perhaps there is a simpler solution, but it's the only thing I managed to do to make this work, hope this helps !

yes i have fixed my problem and got it working.

@iwebnaut please can you place your solution here?

yes of course, what I did I got of my lazy ass and implemented my own slider that matches any feature slick had to begin with and then added more features to it, it took few weeks but I got 100% vue based kick ass slider now :)

same error

the best way is creating your own slide component for Vue.js

Read Wrapper Componnent

as I mentioned above I created my own, its not hard to do. Check the results here

https://www.youtube.com/watch?v=Mg_eG9H3zLM

it entirly vuejs based and no wrappers where needed

@nikocraft good job on making your own :) any chance of making it open-source and adding it to github so we can all benefit from it ;)

@vesper8 its a part of the CMS I am making, I can't easily extract it. CMS should be released next year but that will not help you right now, sorry :)

Worked to me. I used like this:

Component:

<slick ref="carousel">
    <div class="cont" v-for="item in banners">
        <a class="wrap-img" :href="item.url">
            <img :src="item.image" />
        </a>
    </div>
</slick>

And inside my js:


watch: {
    banners: function () {
        let currIndex = this.$refs.carousel.currentSlide()

        this.$refs.carousel.destroy()
        this.$nextTick(() => {
        this.$refs.carousel.create()
        this.$refs.carousel.goTo(currIndex, true)
        })
    }
}

Also I had multiple slideshows (of which I was showing one at a time depending on one prop), so I had to assign different refs and to do the same thing for every ref

I found this did the trick. Destroy and recreate using the lifecycle hooks.

 beforeUpdate() {
    this.$refs.slick.destroy();
      if (this.$refs.slick) {
          this.$refs.slick.destroy();
      }
  },
  updated() {
      this.$nextTick(function () {
          this.$refs.slick.create(this.slickOptions);
      });
  },