首页 文章

在解决Vue路由之前访问Vuex

提问于
浏览
2

我有什么:

  • 路由器,带有auth-required路由和公共路由
    具有用户身份验证状态的
  • vuex

我想要什么:使用 axios 向服务器发送请求以检查用户的身份验证状态 before app已加载(在解析路由器之前) .

router.js

import Vue from 'vue'
import Router from 'vue-router'
import store from './store'

Vue.use(Router)

const router = new Router({
  ...
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/account',
      name: 'account',
      component: () => import(/* webpackChunkName: "account" */ './views/Account.vue'),
      meta: {
        requiresAuth: true
      }
    }
  ]
})

router.beforeEach((to, from, next) => {
  if (to.matched.some(route => route.meta.requiresAuth)) {
    if (store.state.authStatus)
      next()
    else
      next({name: 'home'})
  } else {
    next()
  }
})

export default router

store.js

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

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    authStatus: false
  },
  mutations: {
    setAuthStatus(state, authStatus) {
      state.authStatus = authStatus
    }
  }
})

 axios.get(...)
   .then(response => {
     store.commit('setAuthStatus', true)
   })

export default store

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

My problem :当我在授权时在浏览器中输入 mydomain.com/acount (以前未加载应用程序)时,无论如何我都被重定向到 home . 在重定向之后,我看到我已经被授权(我在Home组件中设置了一些DOM元素,仅为授权用户显示) .


我试过这个,没有帮助:

store.js

const store = new Vuex.Store({
  ...
  actions: {
    setAuthStatus({commit}) {
      axios.get(...)
        .then(response => {
          commit('setAuthStatus', true)
        })
    }
  }
})

main.js

store.dispatch('setAuthStatus').then(() => {
  new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount('#app')
})

编辑:在 main.js 我试图去

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

new Vue({
  store,
  router,
  render: h => h(App)
}).$mount('#app')

它也没有帮助 .

3 回答

  • 1

    绕过Vanojx1's answer,我解决了下一个问题 .

    store.js

    const store = new Vuex.Store({
      state: {
        authStatus: axios.get(...).then(response => {
          store.commit('setAuthStatus', true)
        }),
        userAuth: false
      },
      mutations: {
        setAuthStatus(state, authStatus) {
          state.userAuth = authStatus
        }
      }
    })
    

    router.js

    router.beforeEach((to, from, next) => {
      if (to.matched.some(route => route.meta.requiresAuth)) {
        store.state.authStatus.then(() => {
          //we're getting 200 status code response here, so user is authorized
          //be sure that API you're consuming return correct status code when user is authorized
          next()
        }).catch(() => {
          //we're getting anything but not 200 status code response here, so user is not authorized
          next({name: 'home'})
        })
      } else {
        next()
      }
    })
    
  • 0

    在导航防护中,您需要一些异步,因此在商店中将您的axios承诺保存为authStatus . 当它解析提交并设置loggedIn状态时 . 在导航守卫中等待承诺解决,然后调用下一个功能进入下一个路由器 .

    Store.js

    import Vue from "vue";
    import Vuex from "vuex";
    
    Vue.use(Vuex);
    
    const store = new Vuex.Store({
      state: {
        /*  EXAMPLE
        authStatus: new Promise(resolve => {
          setTimeout(() => {
            const requestResult = true;
            store.commit("setAuthStatus", requestResult);
            resolve(requestResult);
          }, 1000);
        }),
        */
        authStatus: axios.get(...).then((requestResult) => {
            store.commit("setAuthStatus", requestResult);
        }),
        loggedIn: false
      },
      mutations: {
        setAuthStatus(state, loggedIn) {
          state.loggedIn = loggedIn;
        }
      }
    });
    
    export default store;
    

    router.js

    router.beforeEach((to, from, next) => {
      if (to.matched.some(route => route.meta.requiresAuth)) {
        store.state.authStatus.then(loggedIn => {
          if (loggedIn) next();
          else next({ name: "home" });
        });
      } else {
        next();
      }
    });
    

    检查此解决方案是否有效here

  • 1

    问题可能是由于你输入网址https://example.com/account时的问题

    它启动app,axios对服务器执行异步请求 . 所以也许你应该尝试在beforeEach中进行axios调用 .

    通过这种方式,您可以在验证用户身份时遇到任何问题 .

    问题是你不能使axios同步,所以你必须用axios返回一个promise以实现功能 .

    请告诉我这是否有任何帮助 .

相关问题