15
votes

I would like to pass router params into Vuex actions, without having to fetch them for every single action in a large form like so:

edit_sport_type({ rootState, state, commit }, event) {
  const sportName = rootState.route.params.sportName <-------
  const payload = {sportName, event}                 <-------
  commit(types.EDIT_SPORT_TYPE, payload)
},

Or like so,

edit_sport_type({ state, commit, getters }, event) {
  const payload = {sportName, getters.getSportName}  <-------
  commit(types.EDIT_SPORT_TYPE, payload)
},

Or even worse: grabbing params from component props and passing them to dispatch, for every dispatch.

Is there a way to abstract this for a large set of actions?

Or perhaps an alternative approach within mutations themselves?

3

3 Answers

29
votes

To get params from vuex store action, import your vue-router's instance, then access params of the router instance from your vuex store via the router.currentRoute object.

Sample implementation below:

router at src/router/index.js:

import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'

Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  routes
})

export default router

import the router at vuex store:

import router from '@/router'

then access params at vuex action function, in this case "id", like below:

router.currentRoute.params.id
2
votes

Not sure to understand well your question, but :
This plugin keeps your router' state and your store in sync :
https://github.com/vuejs/vuex-router-sync

and it sounds like what you are looking for.

0
votes

To my knowledge ( and I've looked into this for a project I'm working on ) no, there is not. The simplest way to do this is to abstract route fetching or anything you want to do to a service and use it in your vuex file or if you use modular approach import it in you actions.js file.

so paramFetching.js file would look like this:

export default {
  fetchRouteParams: function() {
    // do fetching
    // you should return a promise 
  }
}

Then import that into your vuex

import service from 'paramFetching.js'

And then make an action like so

...
fetchParamsAction: function({commit}) {
  service.fetchRouteParams()
    .then( (response) => { // stuff gottten from service. you should o your commit here } )
    .catch( (error) => { // error handling } )
}

And then just dispatch this action and everything will be handled in an action. So it kinda isolates that from the rest of the code. This is just a general idea. I'm sorry if it's not clear enough. If I can help further, please ask.