Ответ 1
import router from './router'
и использовать router.push
Просто так.
Я создаю веб-приложение с Vue 2.x и Vuex 2.x. Я получаю некоторую информацию из удаленного места через 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:"/"})
дает мне следующую ошибку.
Неподготовлено (в обещании) TypeError: Не удается прочитать свойство "push" из undefined
Как это можно достичь.
Имитированный JsFiddle: здесь
import router from './router'
и использовать router.push
Просто так.
Похоже, вы не вводите свой роутер в свое приложение, следовательно, это "undefined"
В предыдущих версиях 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
во всем приложении
После ответа на соответствующий вопрос: Как использовать Vue Router из состояния Vuex? кажется, что Vuex не получит экземпляр маршрутизатора в this.$router
. Поэтому было предложено два метода для обеспечения доступа к экземпляру маршрутизатора.
Первое более прямое, что связано с установкой глобального веб-пакета в экземпляр.
Вторым является использование Promises с вашим действием vuex, которое позволит вашим компонентам использовать их ссылку на экземпляр маршрутизатора после действий Promise, разрешающих/отклоняющих.
Этот пример может помочь вам.
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},
]
})
import {router} from "../main.js"
export const someAction = ({commit}) => {
router.push("/welcome");
}
Мне не нравилось хранить состояние местоположения моего приложения отдельно от остальной части состояния моего приложения в Магазине и необходимость управлять как Маршрутизатором, так и Магазином, поэтому я создал модуль Vuex, который управляет состоянием местоположения внутри Магазина.
Теперь я могу перемещаться, отправляя действия, как и любое другое изменение состояния:
dispatch("router/push", {path: "/error"})
Это дает дополнительное преимущество, облегчая обработку таких вещей, как переходы анимированных страниц.
Нетрудно свернуть свой собственный модуль router
, но вы также можете попробовать мой, если хотите:
НАЧАЛЬНЫЙ ОТВЕТ
В main.js
(той, где мы "устанавливаем" все модули и создаем экземпляр Vue
, т.е. src/main.js
):
const vm = new Vue({
el: '#app',
router,
store,
apolloProvider,
components: { App },
template: '<App/>'
})
export { vm }
Это мой пример, но в нашем случае наиболее важными здесь являются const vm
и router
В вашем store
:
import { vm } from '@/main'
yourMutation (state, someRouteName) {
vm.$router.push({name: someRouteName})
}
P.S. Используя import { vm } from '@/main'
, мы можем получить доступ ко всему, что нам нужно в Vuex
, например, vm.$root
, что необходимо некоторым компонентам bootstrap-vue
.
P.P.S. Кажется, мы можем использовать vm
только тогда, когда все загружено. Другими словами, мы не можем использовать vm
внутри someMutation
в случае, если мы вызываем someMutation
внутри mounted()
, потому что mounted()
приходит/происходит до того, как будет создан vm
.
НОВЫЙ ОТВЕТ
Константин ответ (принятый) лучше моего, поэтому просто хочу показать новичку, как его реализовать.
Внутри основной директории (внутри /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
:
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(...)