如何从Vuex操作中使用vue router导航

vof42yt1  于 12个月前  发布在  Vue.js
关注(0)|答案(6)|浏览(119)

我正在使用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:无法读取未定义的属性“push”
如何才能做到这一点。
模拟JsFiddle:here

az31mfrm

az31mfrm1#

只要你从应用中的某个地方导出路由器示例(例如./router.js),你就可以将其import用于任何你想要的地方-包括Vuex商店:

import router from './router';

字符串
在这里,您可以使用router.push()
就这么简单。

55ooxyrt

55ooxyrt2#

这个例子可以帮助你。

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

gojuced7

gojuced73#

初始答案

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


P.S.使用import { vm } from '@/main',我们可以访问Vuex中需要的任何内容,例如bootstrap-vue的某些组件需要的vm.$root
P.P.S.似乎我们可以在加载所有内容时使用vm。换句话说,我们不能在someMutation中使用vm,如果我们在mounted()中调用someMutation,因为mounted()vm创建之前出现。

新的答案

Constantin的answer(公认的)比我的好,所以只是想为新手展示如何实现它。
核心目录内(在我的情况下/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(...)

qoefvg9y

qoefvg9y4#

它看起来像你没有注入你的路由器到你的应用程序,因此它是'未定义'
在之前版本的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 resolving / rejecting之后使用它们对路由器示例的引用。

i86rm4rw

i86rm4rw5#

我不喜欢将我的应用的位置状态与应用商店中的其他应用状态分开,并且必须同时管理路由器和应用商店,所以我创建了一个Vuex模块来管理应用商店中的位置状态。
现在我可以通过调度操作来导航,就像任何其他状态更改一样:

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

字符串
这有一个额外的好处,使动画页面过渡等事情更容易处理。
运行自己的router模块并不难,但如果你想的话,你也可以试试我的:
https://github.com/geekytime/vuex-router

gblwokeq

gblwokeq6#

您可以简单地从路由器目录导入路由,如下所示:

import router from '@/router'

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

字符串
此**@**符号替换src目录的路径

相关问题