In vue 2, how is it possible to inject something on the instance depending on the route?

with vue 1 this was working:

route: {
  activate(transition) {
    this.myProp = transition.from.params.prop; 

with vue 2, route.activate is deprecated and the syntax is like:

beforeRouteEnter(to, from, next) {
  this.myProp = from.params.prop;

but the instance (this) is not accessible at this stage. So how is it possible to inject something on the instance depending on the route in vue 2?

thanks

ok I found my answer:

beforeRouteEnter (to, from, next) {
  next(vm => {
    // access to component instance via `vm`
  })
}
1 Like

you can simply do this in the created() hook as well.

how to access the transition object from the created hook?

Oh, that’S not possible of course.

But it seems like a bad idea to have a route that is dependent on a param from the previous route.

That means you can’t link to this route from anywhere als than this previous route that has the param, nor can you visit this rooute directly by clicking on an external link to it or by typing it in the browser’s adress bar yourself.

So what’s the best way to handle the case where a specific transition needs to be fired depending on the route?

for example:

  • if coming from route A, trigger one transition,
  • if coming from route B, trigger another transition inside the destination component.

well, if this is just about animations/transitions, then you can surely use beforeRouteEnter (or the global hook in the router) for this.

Just remember to define what should happen when there’s not previous route.

So, here is my reasoning: I want to trigger a transition or another depending on a local property. The problem with beforeRouteEnter is I have no access to the component’s properties… And I feel the global hook might not be the right place as this is a “local” problem which concern a specific component. Maybe I miss a part of the puzzle… what do you think? : )

You seem to have to share this local prop between the two routes. You have two options.

  • move that local state to global state, e.g. a simple store object or something more advanced liek vuex
  • add this prop as a param or query to the url.

There’s nothing else. you can’t access the previous and new vm at the same time.

1 Like

ok Thanks Linus! I’ve been reading about vuex for too long… I think it’s time to dig into it.

If this is your only state problem, it’s certainly over-engineered. But in general it’s an awesome solution to manage state cleanly.

I tried the same solution as yours, but I got an exception case, and now I understood it.

My program flow is: loading data after clicked button at search page and cache it at $route.params and go to detail page, save data at detail page and close detail page and then back to search page.

partial codes:

to push data and go to next page:

rulePage.$router.push({ name: nextPage, params: { pending$: pendingData || {}, q: rulePage.$root.nextQ() } });

to consume data in target page’s beforeRouteEnter hook, like:

beforeRouteEnter.next( vm => {  /* consume data here */ }) 

to close page.

    cancelPage() {
      this.meta$ = {};
      this.$destroy();
      this.$router.back();
    },

router-view:

<keep-alive :exclude="['LoginForm','ChangePwd']"><router-view :key="$route.fullPath" /></keep-alive>

, this works in my some cases, but, in the following cycles, it fails:

  1. click ‘Maintain’ at Search page to load data and go to Detail page. OK, data shown at detail page.
  2. click ‘Save’ at Detail page to save data and call cancelPage() to return to Search page.
  3. re-do step 1 again. KO, failed, beforeRouteEnter.next( vm => { /* this callback is not called */ }); beforeRouteEnter() itself is called.
  4. cancel Detail page and return to search page, and click ‘Maintain’ again, this time it works.

I can always repeat this, but now I possibly know why callback for next() is not called in 2nd entry.
After I compared my code to another ‘try to simulate it with minimu code lines’, I found, after currentPage.$destroy() called, if my code access this destroyed instance, next time go to page with this component (not re-used because I used an incremental id ‘q’ in route path), it will not call the callback, I guess it possibly hit an invalid case and leave an inconsistent status somewhere.
My code uses $axios to save data with ‘await’ and close page immediately, after page closed, in ‘finally block’ some codes uses the destroyed page component, after I move the ‘cancelPage’ to the last line (after the ‘finally block’ of calling axios), it fixed the problem.

package versions:
├── @vee-validate/i18n@4.5.7
├── @vue/cli-plugin-babel@4.5.15
├── @vue/cli-plugin-router@4.5.15
├── @vue/cli-plugin-vuex@4.5.15
├── @vue/cli-service@4.5.15
├── axios@0.21.4
├── base64url@3.0.1
├── bigdecimal@0.6.1
├── bootstrap-icons-vue@0.8.0
├── bootstrap-vue-treeview@1.0.8
├── bootstrap-vue@2.21.2
├── bootstrap@4.6.1
├── core-js@3.20.2
├── crypto@1.0.1
├── dt-format@1.0.8
├── popper.js@1.16.1
├── sass-loader@10.2.0
├── sass@1.45.2
├── v-contextmenu@2.9.0
├── v-mask@2.3.0
├── vee-validate@3.4.14
├── vue-axios@3.4.0
├── vue-click-outside@1.1.0
├── vue-i18n@8.26.8
├── vue-modal-router@0.6.1
├── vue-router@3.5.3
├── vue-runtime-helpers@1.1.2
├── vue-template-compiler@2.6.14
├── vue@2.6.14
├── vuex@3.6.2
└── webpack@4.46.0

what’s the best way to handle the case where a specific transition needs to be fired depending on the route?

Just remember to define what should happen when there’s not previous route.. .