Vue.js - Get current route in Vuex module
Asked Answered
S

1

6

I have a namespaced vuex store that returns an entry of the store based on the parameter of the current route.

import Router from '../../router/index'

const options = {
  routeIdentifier: 'stepId'
}

export function fromRoute(state) {
  if (!options.routeIdentifier || !Router.currentRoute.params) {
    return null
  }

  return state.all.find(element => {
    return element.identifier === Router.currentRoute.params[options.routeIdentifier]
  })
}

This works as expected for the initial load. However, it is not reloaded whenever the route changes.

Is there a way to reload / force the recalculation of the getter on change of the route?

Sigismondo answered 1/2, 2021 at 15:8 Comment(7)
It would be more supported to import the store in the router module and use a navigation guard to perform whatever you need on routing events. The store is best thought of as global data to be imported into other modules, not vice versa (helper modules aside)Pomegranate
Thanks for the comment! However, I wanted to write a "generic" store I can reuse for multiple namespaced store. My idea was to have a generic "fromRoute" getter that always provides the corresponding entity out of the state. I now chose to expose the getter as method. I therefore have to write a small computed field per component, but it works...Sigismondo
What would the benefit be of that over, say, using beforeEach to set the current route in the store?Pomegranate
i would have to set the currentRoute in every single namespaced store or in my root store. Would a change in my rootState actually trigger the recalc of the getter of my namespaced store?Sigismondo
It would indeed. If you decide you like that more, let me know and I can package it into an answerPomegranate
I guess that would be cleaner as I could remove the computed prop to use the getter for every view / component :) - feel free to post the answer!Sigismondo
For passerby: router.currentRoute._rawValue.params works in newer versions.Shirk
P
6

It would be more supported to import the store in the router module rather than vice versa. You can use the beforeEach navigation guard to set the current route in the store. First, prepare the store:

store.js

state: {
  route: null
},
mutations: {
  SET_ROUTE(state, route) {
    state.route = route;
  }
},
modules: { ... }

In the router module, use the beforeEach guard to store the current route, which is the to argument:

router.js

import store from '@/store';  // Import the store in the router module

const router = new VueRouter({
  ...
})

router.beforeEach((to, from, next) => {
  store.commit('SET_ROUTE', to);
  next();
});

To access this route in a Vuex module getter, access it through the third getter argument, rootState:

store/someModule.js

getters: {
  getRoute(state, getters, rootState) {
    return rootState.route;
  }
}
Pomegranate answered 2/2, 2021 at 12:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.