开发者问题收集

如何使用 Vue Router 从 Vuex 操作进行导航

2016-11-22
108035

我正在使用 Vue 2.x 和 Vuex 2.x 创建一个 Web 应用程序。我正在通过 http 调用从远程位置获取一些信息,我希望如果该调用失败,我应该重定向到其他页面。

GET_PETS: (state) => {
  return $http.get('pets/').then((response)=>{
      state.commit('SET_PETS', response.data)
    })
  },
  error => {this.$router.push({path:"/"}) }
  )
}

但是 this.$router.push({path:"/"}) 给了我以下错误。

Uncaught (in promise) TypeError: Cannot read property 'push' of undefined

如何实现。

模拟 JsFiddle: 此处

3个回答

只要您从应用程序中的某个位置导出路由器实例(例如 ./router.js ),您就可以 导入 它以在任何您想要的地方使用 - 包括进入 Vuex 存储:

import router from './router';

从那里,您可以使用 router.push()

就这么简单。

Marek Urbanowicz
2016-11-22

这个例子可能会对你有帮助。

main.js

import Vue from "vue";
import VueRouter from "vue-router";

...

Vue.use(VueRouter);

export const router = new VueRouter({
    mode: 'hash',
    base: "./",
    routes: [
        { path: "/", component: welcome},
        { path: "/welcome", component: welcome},

    ]
})

actions.js

import {router} from "../main.js"

export const someAction = ({commit}) => {

    router.push("/welcome");
} 
bocai
2016-12-14

初始答案

main.js 中(我们“安装”所有模块并创建 Vue 实例,即 src/main.js ):

const vm = new Vue({
  el: '#app',
  router,
  store,
  apolloProvider,
  components: { App },
  template: '<App/>'
})

export { vm }

这是我的示例,但在我们的例子中,这里最重要的是 const vmrouter

在您的 store 中:

import { vm } from '@/main'

yourMutation (state, someRouteName) {
  vm.$router.push({name: someRouteName})
}

附注:使用 import { vm } from '@/main' ,我们可以访问 Vuex 中所需的任何内容,例如 vm.$root ,它是 bootstrap-vue 的某些组件所需要的。

附注:看来只有在一切都加载完成后我们才能使用 vm 。换句话说,如果我们在 mounted() 内调用 someMutation ,则不能在 someMutation 内使用 vm ,因为 mounted() 在创建 vm 之前出现/发生。


新答案

Constantin 的 答案 (已接受的答案)比我的更好,因此只想向新手展示如何实现它。

在核心目录内(在我的情况下为 /src 内),在 App.vuemain.js 和其他目录旁边,我还有 router.js 内容:

import Vue from 'vue'
import Router from 'vue-router'

// Traditional loading
import Home from '@/components/pages/Home/TheHome'

// Lazy loading (lazy-loaded when the route is visited)
const Page404 = () => import(/* webpackChunkName: "Page404" */ '@/components/pages/404)
const Page503 = () => import(/* webpackChunkName: "Page503" */ '@/components/pages/503)

Vue.use(Router)

const router = new Router({
  mode: 'hash',
  base: process.env.BASE_URL,
  linkExactActiveClass: 'active',
  routes: [
    {
      path: '*',
      name: 'Page404',
      component: Page404
    },

    {
      path: '*',
      name: 'Page503',
      component: Page503
    },

    {
      path: '/',
      name: 'Home',
      component: Home
    },

    // Other routes
    {....},
    {....}
  ]
})

// Global place, if you need do anything before you enter to a new route.
router.beforeEach(async (to, from, next) => {
  next()
})

export default router

将我们的路由器导入 main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

const vm = new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

export { vm }

最后,在你的组件、Vuex 或其他任何地方 import router from './router' 并执行你需要的任何操作,例如 router.push(...)

TitanFighter
2018-11-14