Javascript 如何从Vuex操作使用vue路由器进行导航
我正在使用Vue 2.x和Vuex 2.x创建一个web应用程序。我通过http调用从远程位置获取一些信息,我希望如果调用失败,我应该重定向到其他页面Javascript 如何从Vuex操作使用vue路由器进行导航,javascript,vue.js,vuex,Javascript,Vue.js,Vuex,我正在使用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:"
GET_PETS: (state) => {
return $http.get('pets/').then((response)=>{
state.commit('SET_PETS', response.data)
})
},
error => {this.$router.push({path:"/"}) }
)
}
但是this.$router.push({path:“/”})
给了我以下错误
未捕获(承诺中)TypeError:无法读取未定义的属性“push”
如何才能做到这一点
模拟JSFIDLE:
从“/router”导入路由器
并使用路由器。按
很简单。看起来你没有将路由器注入你的应用程序,因此它是“未定义的” 在以前版本的vue路由器中,您可以:
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似乎不会在
this.$router
接收路由器实例。因此,建议使用两种方法来提供对路由器实例的访问
第一个更直接,它涉及到为实例设置一个webpack全局
第二种方法涉及在vuex操作中使用承诺,这将允许组件在承诺解决/拒绝操作后利用对路由器实例的引用。此示例可能会对您有所帮助 main.js actions.js
我不喜欢将应用程序的位置状态与应用程序在应用程序商店中的其他状态分开,并且必须同时管理路由器和应用程序商店,因此我创建了一个Vuex模块来管理应用程序商店中的位置状态 现在,我可以通过调度操作导航,就像任何其他状态更改一样:
dispatch("router/push", {path: "/error"})
这样做的另一个好处是使动画页面转换等操作更容易处理
推出您自己的路由器
模块并不难,但如果您想:
初始答案 在
main.js
(我们“安装”所有模块并创建Vue
实例,即src/main.js
)中:
另外,使用“@/main”中的import{vm}
我们可以访问Vuex
中需要的任何内容,例如vm.$root
,这是引导vue
的某些组件所需要的
p.p.S.似乎我们可以在加载所有内容时使用vm
。换句话说,如果我们调用someMutation
insidemounted()
,我们不能在someMutation
中使用vm
,因为mounted()
发生在vm
创建之前
新答案 Constantin的(公认的)比我的好,所以我只想向新手展示如何实现它 内部核心目录(在我的例子中是内部
/src
),旁边是App.vue
,main.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
:
const vm = new Vue({
el: '#app',
router,
store,
apolloProvider,
components: { App },
template: '<App/>'
})
export { vm }
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或任何其他
从“./router”
导入路由器,并执行您需要的任何操作,例如路由器。推送(…)
您只需从路由器目录导入路由,如下所示:
从“@/router”导入路由器
router.push({name:'Home'})
此@符号取代了src目录的路径这应该是vue 2的专用答案,因为您在将“this”视为文字的箭头函数中使用它。要么将其转换为常规函数,要么使用下面建议的答案……这不是使用Vue的方式。行动不应该有副作用。用组件的方法解决这个问题,比如
dispatch('someAction')。然后(()=>this.$router.push('/welcome'))
@adrian不是严格正确的,甚至vuex演示中的操作也有副作用。
import { vm } from '@/main'
yourMutation (state, someRouteName) {
vm.$router.push({name: someRouteName})
}
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
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 }