Owl Carousel + Vue.js with dynamic item

0

Hello, I have a component that initializes a slider with dynamic items coming from the database. However, I have a search box that makes a new request to the database and returns new items to replace the existing ones in the slider. But it is not replacing, being over the slider.

The component template code follows: (There is always a default (banner_default) item that should always be the first slide of the slider)

<template>
<div @click.prevent="refresh()" class="week-slider valign-wrapper"><i class="fa fa-home" aria-hidden="true"></i></div>
<div id="feupworld_slide" class="owl-carousel owl-theme">
    <div class="item">
        <div class="textoverlay firstSlide"><span>{{ week }} / {{ year }}</span></div>
        <img :src="'storage/guest/' + banner_default" alt="#FEUPWORLD">
    </div>
    <div class="item" v-for="slide in slider">
        <div class="textoverlay captionSlide flow-text">
            <a :href="slide.link" target="_blank">
            <span class="background-slide-text show-link" style="font-size: 2.0vw;">{{ slide.title }}</span>
            </a>
            <div style="" class="hashtag">
                <span class="light grey-text text-lighten-3 tags-slide background-slide-text">
                    <span v-for="tag in slide.tags" class="tags" style="font-size: 1.1vw;">#{{ tag.tag }} </span>
                </span>
            </div>
        </div>
        <img :src="'storage/noticias/images/' + slide.photo " alt="#FEUPWORLD">
    </div>
</div>

Follow the script:

<script type="text/javascript">

export default{
    data(){
        return{
            slider: [],
            week: 0,
            init: false,
            banner_default: "banner_default.jpg",
            year: new Date().getFullYear(),
            link: "",
        }
    },
    created(){
        this.imageSlider();
    },
    methods:{
        refresh(){
            location.reload();
        },
        imageSlider(){
            Vue.http.get('imageSlider').then((response) => {
                this.slider = response.data.data;
                this.week = response.data.data[0].week;
            });
            window.Vue.http.interceptors.unshift((request, next) => {
                next(()=> {
                    this.sliderInit();
                });
            });
        },
        sliderInit(){
            if(!this.init){
                this.init = true;
                Vue.nextTick(function () {
                    $("#feupworld_slide").owlCarousel({
                        singleItem:false,
                        items: 1,
                        autoplay: true,
                        autoPlaySpeed: 3000,
                        autoPlayTimeout: 3000,
                        dots: true,
                        loop:true,
                        pagination: true,
                    });
                }.bind(this));
            }
        },
        showWeekYearSlider(){
            this.slider = [];
            Vue.http.get('getimageSliderWeekYear/'+this.year+'/'+this.week).then((response) => {
                this.slider = response.data.data;
            });
        }
    },
    events: {
        'selectBanner'(data){
            this.week = data.week;
            this.year = data.year;
            this.showWeekYearSlider();
        },
    },
}

The event "selectBanner" calls the function that should subscribe the old slides for the new ones, it follows a print of what it is doing to me (it overlaps the new images to me on top of the slider one underneath the others):

Thenextimagelooksatthe"1" slides new over the old slide and "2" shows the bullets with the number of previous items but now are left blank and only the default slider, which is correct, remains.

    
asked by anonymous 01.02.2018 / 17:37

1 answer

0

I have been through this problem for a while, in my case I needed to encapsulate the owl-carousel within a component.

owl-carousel.vue

<template>
  <ul>
    <slot></slot>
  </ul>
</template>

<script src="./owl-carousel.vue.js"></script>
<style src="./owl-carousel.vue.css"></style>

owl-carousel.vue.js

import './assets/owl.carousel.css'
import './assets/owl.theme.css'
import './assets/owl.carousel.js'

export default {
  name: 'OwlCarousel',
  props: {
    items: Number,
    itemsDesktopSmall: Array,
    itemsTablet: Array,
    itemsTabletSmall: Array,
    itemsMobile: Array,
    value: Array
  },
  data () {
    return {
      widget: null
    }
  },
  computed: {
    options () {
      return {
        items: this.items,
        itemsDesktopSmall: this.itemsDesktopSmall,
        itemsTablet: this.itemsTablet,
        itemsTabletSmall: this.itemsTabletSmall,
        itemsMobile: this.itemsMobile,
        navigation: false,
        slideSpeed: 300,
        pagination: true,
        paginationSpeed: 400,
        singleItem: (this.items || 1) === 1,
        navigationText: ['<span class="fa fa-angle-left"></span>', '<span class="fa fa-angle-right"></span>'],
        autoPlay: false
      }
    }
  },
  watch: {
    value: {
      immediate: true,
      handler: function () {
        if (this.widget) {
          this.widget.trigger('destroy.owl.carousel')
          this.widget = null;
        }
        if (this.value && this.value.length > 0) {
          this.$nextTick(() => {
            this.widget = $(this.$el).owlCarousel(this.options)
          })
        }
      }
    }
  }
}

Here is an example of using the .com:

<owl-carousel :items="3" :items-desktop-small="[1280,3]" :items-tablet="[900,2]" :items-tablet-small="[750,2]" :items-mobile="[600,1]" v-model="items">
    <li v-for="item in items" :key="item._id">
        ...
    </li>
</owl-carousel>

If the carousel has no dynamic items (which was not our case), it is interesting that you add the v-once directive to it. The reason for this is well explained in the following article: How To (Safely) Use A jQuery Plugin With Vue.js

<owl-carousel :items="3" :items-desktop-small="[1280,3]" :items-tablet="[900,2]" :items-tablet-small="[750,2]" :items-mobile="[600,1]" v-model="items" v-once>
    <li v-for="item in items" :key="item._id">
        ...
    </li>
</owl-carousel>

In my case, I was using a third-party template, and the theme of it was very customized, so owl-carousel became a somewhat attached dependency.

But in general, you should avoid using components based on jQuery , after all Vue is quite possessive as DOM and jQuery is a terrorist who does not respect this.

At this point Vue Awesome is your friend .: Carousel

    
22.03.2018 / 14:25