How to use Vue Router from Vuex state?

旧城冷巷雨未停 提交于 2019-12-08 16:37:41

问题


In my components I've been using:

this.$router.push({ name: 'home', params: { id: this.searchText }});

To change route. I've now moved a method into my Vuex actions, and of course this.$router no longer works. Nor does Vue.router. So, how do I call router methods from the Vuex state, please?


回答1:


I'm assuming vuex-router-sync won't help here as you need the router instance.

Therefore although this doesn't feel ideal you could set the instance as a global within webpack, i.e.

global.router = new VueRouter({
  routes
})

const app = new Vue({
  router
  ...

now you should be able to: router.push({ name: 'home', params: { id: 1234 }}) from anywhere within your app


As an alternative if you don't like the idea of the above you could return a Promise from your action. Then if the action completes successfully I assume it calls a mutation or something and you can resolve the Promise. However if it fails and whatever condition the redirect needs is hit you reject the Promise.

This way you can move the routers redirect into a component that simply catches the rejected Promise and fires the vue-router push, i.e.

# vuex
actions: {
  foo: ({ commit }, payload) =>
    new Promise((resolve, reject) => {
      if (payload.title) {
        commit('updateTitle', payload.title)
        resolve()
      } else {
        reject()
      }
    })

# component
methods: {
  updateFoo () {
    this.$store.dispatch('foo', {})
      .then(response => { // success })
      .catch(response => {
        // fail
        this.$router.push({ name: 'home', params: { id: 1234 }})
      })



回答2:


I believe rootState.router will be available in your actions, assuming you passed router as an option in your main Vue constructor.

As GuyC mentioned, I was also thinking you may be better off returning a promise from your action and routing after it resolves. In simple terms: dispatch(YOUR_ACTION).then(router.push()).




回答3:


I a situation, I find myself to use .go instead of .push.

Sorry, no explanation about why, but in my case it worked. I leave this for future Googlers like me.




回答4:


    state: {
        anyObj: {}, // Just filler
        _router: null // place holder for router ref
    },
    mutations: {
        /***
        * All stores that have this mutation will run it
        *
        *  You can call this in App mount, eg...

        *  mounted () {
        *    let vm = this
        *    vm.$store.commit('setRouter', vm.$router)
        *  }
        *
        setRouter (state, routerRef) {
            state._router = routerRef
        }
    },
    actions: {
        /***
        * You can then use the router like this
        * ---
        someAction ({ state }) {
            if (state._router) {
                state._router.push('/somewhere_else')
            } else {
                console.log('You forgot to set the router silly')
            }
        }
    }
}



来源:https://stackoverflow.com/questions/40767874/how-to-use-vue-router-from-vuex-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!