wake-up-neo.net

Zugriff auf den Vuex-Status bei der Definition von Vue-Router-Routen

Ich habe den folgenden Vuex Store (main.js):

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

//init store
const store = new Vuex.Store({
    state: {
        globalError: '',
        user: {
            authenticated: false
        }
     },
     mutations: {
         setGlobalError (state, error) {
             state.globalError = error
         }
     }
})

//init app
const app = new Vue({
    router: Router,
    store,
    template: '<app></app>',
    components: { App }
}).$mount('#app')

Ich habe auch die folgenden Routen für Vue-Router (routes.js) definiert:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

//define routes
const routes = [
    { path: '/home', name: 'Home', component: Home },
    { path: '/login', name: 'Login', component: Login },
    { path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]

Ich versuche, es so zu gestalten, dass der Router auf die Anmeldeseite umgeleitet wird, wenn das user-Objekt des Vuex-Stores authenticated auf false festgelegt hat.

Ich habe das:

Router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresLogin) && ???) {
        // set Vuex state's globalError, then redirect
        next("/Login")
    } else {
        next()
    }
})

Das Problem ist, dass ich nicht weiß, wie ich auf das user-Objekt des Vuex-Speichers von der beforeEach-Funktion aus zugreifen kann.

Ich weiß, dass ich die Router-Schutzlogik in Komponenten verwenden kann, die BeforeRouteEnter verwenden, aber dies würde jede Komponente stören. Ich möchte es stattdessen zentral auf Routerebene definieren.

15
Ege Ersoz

Wie vorgeschlagen, hier , können Sie Ihren Shop aus der Datei exportieren, in der er sich befindet, und ihn in routes.js importieren. Es wird so etwas wie das Folgende sein:

Sie haben ein store.js:

import Vuex from 'vuex'

//init store
const store = new Vuex.Store({
    state: {
        globalError: '',
        user: {
            authenticated: false
        }
     },
     mutations: {
         setGlobalError (state, error) {
             state.globalError = error
         }
     }
})

export default store

Jetzt in routes.js können Sie Folgendes haben:

import Vue from 'vue'
import VueRouter from 'vue-router'
import store from ./store.js

Vue.use(VueRouter)

//define routes
const routes = [
    { path: '/home', name: 'Home', component: Home },
    { path: '/login', name: 'Login', component: Login },
    { path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]

Router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresLogin) && ???) {
        // You can use store variable here to access globalError or commit mutation 
        next("/Login")
    } else {
        next()
    }
})

In main.js können Sie auch store importieren:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

import store from './store.js'

//init app
const app = new Vue({
    router: Router,
    store,
    template: '<app></app>',
    components: { App }
}).$mount('#app')
20
Saurabh

Am Ende habe ich den Store aus main.js in store/index.js verschoben und in die Datei router.js importiert:

import store from './store'

//routes

const routes = [
    { path: '/home', name: 'Home', component: Home },
    { path: '/login', name: 'Login', component: Login },
    { path: '/secret', name: 'Secret', component: SecretPage, meta: { requiresLogin: true }
]    

//guard clause
Router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresLogin) && store.state.user.authenticated == false) {
        store.commit("setGlobalError", "You need to log in before you can perform this action.")
        next("/Login")
    } else {
        next()
    }
})
1
Ege Ersoz

Wenn Sie den Standortstatus getrennt vom Rest des Anwendungsstatus verwalten, kann dies schwieriger werden, als dies möglicherweise erforderlich ist. Nachdem ich mich mit ähnlichen Problemen in Redux und Vuex befasst hatte, begann ich mit der Verwaltung meines Standortstatus in in meinem Vuex-Store mithilfe eines router-Moduls. Vielleicht möchten Sie über diesen Ansatz nachdenken.

In Ihrem speziellen Fall könnten Sie beobachten, wenn sich der Standort im Vuex-Store selbst ändert, und die entsprechende "Weiterleitungsaktion" wie folgt auslösen:

dispatch("router/Push", {path: "/login"})

Es ist einfacher als Sie denken, den Standortstatus als Vuex-Modul zu verwalten. Sie können meine als Ausgangspunkt verwenden, wenn Sie es ausprobieren möchten: 

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

1
Chris Jaynes

So würde ich es machen.

In App.vue bewahre ich ein Cookie auf, das Authentifizierungsdetails speichert. (Natürlich würde ich ein Token mit Authentifizierungsdetails nach der Authentifizierung als Cookie speichern.)

Wenn dieses Cookie jetzt leer wird, leite ich den Benutzer zur/Login-Seite. Durch Abmelden wird der Cookie gelöscht. Wenn der Benutzer nach dem Abmelden wieder zurückschlug, da der Cookie jetzt nicht existiert (dazu muss der Benutzer angemeldet sein), wird der Benutzer zur Anmeldeseite weitergeleitet.

0
chirag jain