Vue-router: Ability to hook in afterEach after the transition

Created on 8 Jan 2018  路  6Comments  路  Source: vuejs/vue-router

What problem does this feature solve?

When implementing analytics with vue-router, we often rely on the router.afterEach hook. For example:

router.afterEach((to, from) => {
  ga('set', 'page', to.fullPath)
  ga('send', 'pageview')
})

However, when there is a page transition (and obviously the page transition will use mode="out-in"), the new component will wait for the old component to fade out first, but the afterEach hook was already fired.

In the about example, say the user was originally on the home page with page title "home" and clicks on the /about link:

  1. The url changes immediately, and afterEach hook fires. ga called to track pageview, but got the old title "home" by calling document.title.
  2. The home page fades out, and finally destroyed.
  3. The about page gets mounted (and fades in), page title and other metadata get modified (in my case I'm using vue-meta

In this comment, @posva recommend using Vue.nextTick. I tried adding multiple nextTicks but doesn't work...

What does the proposed API look like?

Is it possible to perhaps dynamically register a mounted hook (without overriding original one) to the to component in afterEach?
For example:

router.afterEach((to, from) => {
  // some kind of way to get the page component
  to.$el.mounted = () => {
    ga('set', 'page', to.fullPath)
    ga('send', 'pageview')
  }
})

Or maybe add a new hook that will wait for page transition to finish, and the new component mounted?

router.afterEachMounted((to, from) => {
  ga(...)
})

Thank you all so much!!!

Dax

fixed on 4.x group[transition wrapped views] improvement

Most helpful comment

@studstill
Thank you! In a lot of case nextTick is really useful.

However, in the case where router-view is wrapped in transition mode="out-in", router.afterEach is actually called right when the old page starts to fade out.

Even with nextTick, the ga(...) call is called one tick after the old page starts to fade out, still resulting in getting the old document.title...

All 6 comments

There are indeed some improvements to have in the navigation cycle to allow users branch anywhere. Specifically when dealing with transitions

I wonder if there is any temporarily workarounds? Without hard-coding something like setTimout(trackingCode, transitionDuration) in router.afterEach

Leverage Vue.nextTick to wait for DOM updates before firing analytics events
```javascript
router.afterEach((to, from) => {
Vue.nextTick(() => {
ga(...)
})
})

@studstill
Thank you! In a lot of case nextTick is really useful.

However, in the case where router-view is wrapped in transition mode="out-in", router.afterEach is actually called right when the old page starts to fade out.

Even with nextTick, the ga(...) call is called one tick after the old page starts to fade out, still resulting in getting the old document.title...

Any updates on this? I'm having the same issues.

Was this page helpful?
0 / 5 - 0 ratings