vue.jsvue-componentvue-routerfouc

How to stop FOUC when leaving route with 'vue-flickity' carousel/slider?


I'm using the vue-flickity package for MetaFizzy's Flickity in my Vue app. When navigating away from a route that has an instance of vue-flickity slider, you get a brief FOUC showing all the slides unstyled in the document as the <Flickity /> slider is dismounted(?) and the view changes.

I've tried wrapping it in a <keep-alive>, but that doesn't help.

What would be the best approach to hiding or "animating out" the component before the user navigates away from a route?

I also tried to use beforeRouteLeave(), transition opacity on <Flickity ref="mySlider" /> to 0, then change route. I tried something like the following, but it didn't work as expected:

// SliderView.vue

<template>
  <Flickity ref="mySlider">
    <div v-for="(slide, index) in slides" :key="index">
      // slide content markup
    </div>
  </Flickity>
</template>

<script>
  import 'Flickity' from 'vue-flickity'

  export default {
    name: 'SliderView'
  }
</script>
// router.js

import Vue from 'vue'
import Router from 'vue-router'
import SliderView from './views/SliderView.vue'

export default new Router({
  routes: [
    {
      path: '/routeWithSlider',
      component: SliderView,
      beforeRouteLeave (to, from, next) {

        const slider = this.$refs.mySlider

        if (slider) {
          slider.style.transition = 'opacity .5s'
          slider.style.opacity = 0
          setTimeout(() => {
            next()
          }, 600)
        } else {
          next()
        }
      }
    }
  ]
})

Is this the correct approach, or should I be approaching this differently?

Also, if there was a way to do this globally for all <Flickity /> instances on all routes without specifying refs, that would also be useful too.

I haven't been using Vue for that long, so am looking for some guidance on the direction to take.


Solution

  • I found the best way to acheive this is to use BeforeRouteLeave() lifecycle hook on the component with the slider to animate the Flickity slider exit before changing route:

    beforeRouteLeave (from, to, next) {
      const slider = this.$refs.flickity.$el
      slider.style.transition = 'opacity .25s ease'
      slider.style.opacity = 0
      setTimeout(() => {
        next()
      }, 250)
    }