94

我正在使用 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:这里

4

6 回答 6

213

import router from './router'

并使用router.push

就这么简单。

于 2016-11-22T08:23:32.487 回答
19

这个例子可以帮助你。

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},

    ]
})

动作.js

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

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

    router.push("/welcome");
} 
于 2016-12-14T08:59:30.710 回答
11

看起来您没有将路由器注入您的应用程序,因此它是“未定义的”

在以前的 vue-router 版本中,您可以:Vue.use(VueRouter)使用 2.0,您可以将路由器注入到应用程序中,如下所示:

const routes = [
  { path: '/foo', component: Foo },
]

const router = new VueRouter({
  routes
})

const app = new Vue({
  router // inject the router
}).$mount('#app')

这应该使它在this.$router整个应用程序中都可用


在回答相关问题之后:如何从 Vuex 状态使用 Vue Router?看来 Vuex 不会在this.$router. 因此,建议使用两种方法来提供对路由器实例的访问。

第一个更直接,它涉及为实例设置一个全局的 webpack。

第二个涉及将 Promises 与您的 vuex 操作一起使用,这将允许您的组件在 Promise 解析/拒绝操作之后利用它们对路由器实例的引用。

于 2016-11-22T15:19:16.327 回答
10

初步答案

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})
}

PS使用import { vm } from '@/main'我们可以访问我们需要的任何东西Vuex,例如vm.$root某些组件需要的bootstrap-vue

PPS 似乎我们可以vm在加载所有内容时使用。换句话说,如果我们调用inside ,我们不能使用vminside ,因为在创建之前出现/发生。someMutationsomeMutationmounted()mounted()vm


新答案

康斯坦丁的答案(被接受的)比我的要好,所以只想向新手展示如何实现它。

内部核心目录(/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(...)

于 2018-11-14T22:04:34.810 回答
7

我不喜欢将我的应用程序的位置状态与商店中的其他应用程序状态分开,并且必须同时管理路由器和商店,因此我创建了一个 Vuex 模块来管理商店的位置状态。

现在我可以通过调度操作进行导航,就像任何其他状态更改一样:

dispatch("router/push", {path: "/error"})

这还有一个额外的好处,就是让动画页面转换之类的事情更容易处理。

推出自己的router模块并不难,但如果你愿意,也可以试试我的:

https://github.com/geekytime/vuex-router

于 2018-03-30T13:52:57.037 回答
2

您可以像这样简单地从路由器目录导入路由:

import router from '@/router'

router.push({name: 'Home'})

这个@符号替换了src目录的路径

于 2021-03-09T14:07:31.537 回答