Je crée une application Web avec Vue 2.x et Vuex 2.x. Je vais chercher des informations à distance via un appel http, je veux que si cet appel échoue, je devrais rediriger vers une autre page.
GET_PETS: (state) => {
return $http.get('pets/').then((response)=>{
state.commit('SET_PETS', response.data)
})
},
error => {this.$router.Push({path:"/"}) }
)
}
Mais this.$router.Push({path:"/"})
me donne l'erreur suivante.
Non capturé (promis) TypeError: Impossible de lire la propriété 'Push' of indéfinie
Comment cela peut il etre accompli.
JsFiddle simulé: ici
import router from './router'
et utilisez router.Push
Aussi simple que ça.
Il semble que vous n'injectiez pas votre routeur dans votre application, ce qui explique son indétermination.
Dans les versions précédentes de vue-router, vous devriez: Vue.use(VueRouter)
, avec la version 2.0, vous pouvez injecter le routeur dans l'application comme ci-dessous:
const routes = [
{ path: '/foo', component: Foo },
]
const router = new VueRouter({
routes
})
const app = new Vue({
router // inject the router
}).$mount('#app')
cela devrait alors le rendre disponible en tant que this.$router
dans toute l'application
Après avoir répondu à une question connexe: Comment utiliser Vue Router à partir de l’état Vuex? il semble que Vuex ne reçoive pas l'instance de routeur à this.$router
. Par conséquent, deux méthodes ont été suggérées pour fournir un accès à l'instance de routeur.
La première est plus directe, ce qui implique de définir un pack Web global pour l'instance.
La seconde consiste à utiliser Promises avec votre action vuex pour permettre à vos composants d’utiliser leur référence à l’instance de routeur après les actions de résolution/rejet de Promise.
Cet exemple peut vous aider.
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");
}
Je n'aimais pas que l'état de l'emplacement de mon application soit séparé du reste de l'état de celui-ci dans la boutique et qu'il faille gérer à la fois un routeur et un magasin. J'ai donc créé un module Vuex qui gère l'état de localisation dans le Le magasin.
Maintenant, je peux naviguer en distribuant des actions, comme tout autre changement d'état:
dispatch("router/Push", {path: "/error"})
Cela présente l'avantage supplémentaire de faciliter la gestion d'éléments tels que les transitions de page animées.
Ce n'est pas difficile de lancer votre propre module router
, mais vous pouvez aussi essayer le mien si vous voulez:
Dans main.js
(celui dans lequel nous "installons" tous les modules et créons une instance Vue
, c'est-à-dire src/main.js
):
const vm = new Vue({
el: '#app',
router,
store,
apolloProvider,
components: { App },
template: '<App/>'
})
export { vm }
Ceci est mon exemple, mais dans notre cas, le plus important ici est const vm
et router
Dans votre store
:
import { vm } from '@/main'
yourMutation (state, someRouteName) {
vm.$router.Push({name: someRouteName})
}
P.S. En utilisant import { vm } from '@/main'
, nous pouvons accéder à tout ce dont nous avons besoin dans Vuex
, par exemple vm.$root
, nécessaire à certains composants de bootstrap-vue
.
P.P.S. Il semble que nous pouvons utiliser vm
au moment même où tout est chargé. En d'autres termes, nous ne pouvons pas utiliser vm
dans someMutation
au cas où, si nous appelons someMutation
dans mounted()
, car mounted()
arrive/se produit avant que vm
soit créé.