Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

problems with reSlick #45

Closed
nikocraft opened this issue Oct 8, 2017 · 15 comments
Closed

problems with reSlick #45

nikocraft opened this issue Oct 8, 2017 · 15 comments

Comments

@nikocraft
Copy link

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.

@staskjs
Copy link
Owner

staskjs commented Oct 11, 2017

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

@eaguad1337
Copy link

eaguad1337 commented Nov 15, 2017

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();
            })
          })

@sayhicoelho
Copy link

Same problem here...

@Pimeko
Copy link

Pimeko commented Dec 5, 2017

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 !

@nikocraft
Copy link
Author

yes i have fixed my problem and got it working.

@sayhicoelho
Copy link

@iwebnaut please can you place your solution here?

@nikocraft
Copy link
Author

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 :)

@lchhieu
Copy link

lchhieu commented Apr 6, 2018

same error

@sayhicoelho
Copy link

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

Read Wrapper Componnent

@nikocraft
Copy link
Author

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

ChristianMurphy added a commit to ChristianMurphy/uPortal-web-components that referenced this issue Jul 25, 2018
reSlick is currently broken staskjs/vue-slick#45
So this works around the issue by destroying and recreating the slick
instance when the items change.
@vesper8
Copy link

vesper8 commented Dec 26, 2018

@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 ;)

@nikocraft
Copy link
Author

@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 :)

@luizpaulo165
Copy link

luizpaulo165 commented Feb 4, 2019

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)
        })
    }
}

@gtempesta-pixartprinting

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

@jpaltny
Copy link

jpaltny commented Mar 11, 2022

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);
      });
  },

@Efcolipt Efcolipt closed this as completed Jun 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests