Search code examples
vue.jstransitionnuxt.jsreusability

Nuxt reusable dynamic custom page transition with javascript hooks?


I have a Nuxt.js site that I'm trying to get some fancy page transitions working on. I think I understand how you're supposed to use the transition setting when it's just CSS, but how do I make it reusable with JavaScript hooks?

It seems to me we should be able to do something like this:

// In a Page.vue template 
    transition(to, from) {
        if (!from) {
            return "fade"
        }
        if (to.name == "directors-name-work") {
            // Animate to video playing
            return "to-video"
        }
        if (from.name == "directors-name-work") {
            // Scroll to slideshow, and at same video we just came from.
            return "from-video"
        }
    }

And then I need to be able to define what the JS hooks are for to-video and from-video in JavaScript somewhere, but I have no idea where that goes? Where does enter() and beforeEnter() hooks get defined for the separate transitions? It makes sense if we just have one transition, then I could do it in a mixin. But when it is dynamic I have no idea.

Is there a file I should be putting somewhere called transition-to-video and transition-from-video?


Solution

  • It's currently undocumented, but the page's transition function can return a transition object, which may include the transition JavaScript hooks. This allows you to define your shared transition objects in a common file, and import them into a page as needed:

    ~/transitions.js:

    export default {
      fade: {
        name: 'fade',
        mode: 'out-in',
        beforeEnter(el) {
          console.log('fade beforeEnter')
        }
      },
      bounce: {
        name: 'bounce',
        afterEnter(el) {
          console.log('bounce afterEnter')
        }
      },
    }
    

    ~/pages/about.vue:

    <script>
    import transitions from '~/transitions'
    
    export default {
      transition(to, from) {
        return to.query.fade ? transitions.fade : transitions.bounce
      },
    }
    </script>