Skip to content

Transition effects when route slug changes #474

@jsiebach

Description

@jsiebach

Edit: as I finally got this working, I realized it was very similar to vuejs/vuex-router-sync#3 . The ability to call actions within router hooks ended up being what solved it. So I guess this may be fixed when router hooks are simplified. But the ability to put a transition on a watched variable still makes sense, so I'm posting this anyway.


TL;DR: It would be a feature to allow a transition when data changes. IE if you have <span>Name: {{name}}</span> and name is changed, it would fade-out and then fade-in.


I've used <router-view transition="fade" transition-mode="in-out"> to provide a fade-out, fade-in effect when changing from one route to another. Now I'm having trouble doing the same thing where the route slug changes, but the component and the route are remaining the same.

I've got a Page component that uses a vuex getter to return the content of the current page based on the URL. The route is available in the state thanks to vuex-router-sync:

function getCurrentPage (state) {
  var pages = state.pages.filter(page => page.slug === state.route.params.slug)
  return pages.length ? pages[0] : {}
}

Then I am able to access the current page via this getter in my Page.vue component:

<template>
  <div>
    <div class="content-header">
      <h1>{{{page.title.rendered}}}</h1>
    </div>
    <div class="content-body">
      {{{page.content.rendered}}}
    </div>
  </div>
</template>
<script type="text/babel">
  import {getCurrentPage} from './../vuex/getters'
  export default {
    name: 'Page',
    vuex: {
      getters: {
        page: getCurrentPage
      }
    }
  }
</script>

So when the URL updates, the page content immediately updates. I cannot seem to find a way to use a fade-out, fade-in effect on this change.

  1. Since the route is not changing, the <router-view> transition is not triggered
  2. Since the component is not changing, I can't use an :is="component" transition

I tried a couple of things, like placing a setTimeout in the route.data() function that delayed next() by some time:

    route: {
      data ({next}) {
        setTimeout(()=>{
          next()
        },150);
      }
    }

Then I hid the component during $routeDataLoading. I got a proper fade out fade in effect, however the page variable updated immediately, so the page content updated before the fade-out even began.

What I finally did to get it going was a hack to allow actions within router hooks:

route: {
      data ({to,next}) {
        setTimeout(()=>{
          next({
            page:getCurrentPage(to.router.app.$store.state)
          })
        },150);
      }
    }

Since my fade is .15s, this faded out the div during $routeDataLoading, and then faded it back perfectly .15s later when the timeout finished.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions