在 beforeEach 期间将 vuex 模块状态传递给 vue-router

Posted

技术标签:

【中文标题】在 beforeEach 期间将 vuex 模块状态传递给 vue-router【英文标题】:Passing vuex module state into vue-router during beforeEach 【发布时间】:2017-02-17 20:03:19 【问题描述】:

我将 VueJS 与 vuexvue-router 结合使用。我有一个 vuex 模块正在对其存储进行突变,并尝试使用它来确定用户是否经过身份验证。

这是我的代码在相关部分的样子。

ma​​in.js

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

router.beforeEach((to, from, next) => 
    console.log(router.app) // prints a Vue$2 object
    console.log(router.app.$store) // undefined
    console.log(store.getters.isAuthenticated) // false
    ...


const app = new Vue(
  store,
  router,
  ...App
)

app.$mount('#app')

/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import core from './modules/core'

Vue.use(Vuex)

const store = new Vuex.Store(
  modules: 
    core: core
  
)

export default store

/store/modules/core.js

import * as types from '../types'
import api from '../../api'
import router from '../../router'

const state = 
  token: null,
  user: null,
  authenticated: false


const mutations = 
  [types.LOGIN_SUCCESS] (state, payload) 
    console.log('mutate')
    state.token = payload.token
    state.user = payload.user
    state.authenticated = true
    router.go('/')
  


const getters = 
  isAuthenticated: state => 
    return state.authenticated
  


const actions = 
  [types.LOGIN] (context, payload) 
    api.getToken(payload).then(response => 
      context.commit(types.LOGIN_SUCCESS, response)
    )
  


export default 
  state,
  mutations,
  actions,
  getters

当我通过我的逻辑触发 LOGIN 操作时,我可以看到突变正确执行,当我使用 Chrome 扩展程序查看我的 core 模块的 vuex 状态时,@987654330 的状态@ 和 authenticated 已正确变异。

问题

看起来这个模块只是在路由器在.beforeEach 循环中运行时还没有加载。这是真的吗?

如果是,对于如何处理这种情况,还有哪些其他建议? 如果没有,我做错了什么?

【问题讨论】:

登录store.state.core.authenticated会得到什么? @francoisromain console.log(store.state.core.authenticated) 返回false 我想我找到了问题所在。但是,直到我做更多的研究......我不会发布我自己的答案。似乎状态不是持久的,并且没有使用 html5 localstorage 之类的东西。因此,在每次页面加载时,状态都是空的。所以,我需要将我的用户移动到本地存储(或类似的)以获得这种持久性。我有一个可行的解决方案,当我确定这是最好的方法时,我会发布它。 @TheBrewmaster 也许这会有所帮助.. github.com/Ridermansb/vuex-router-auth0-example 【参考方案1】:

console.log(store.state.core.authenticated) return false 因为你还没有登录。

在您的代码中,您不会在任何地方保留用户信息。例如。使用本地存储

同样的考虑:

    不使用router.app.$store,使用您导入的store 在您的 LOGIN_SUCCESS 突变中,将登录信息和令牌存储到本地存储中 在您的beforeEach 挂钩中,检查localstorage,如果填充了令牌,则获取用户信息并应用突变。如果没有,只需调用登录页面

像这样..

const mutations = 
  [types.LOGIN_SUCCESS] (state, payload) 
    state.token = payload.token
    state.user = payload.user
    state.authenticated = true
    localstorage.setItem('token', payload.token)
    localstorage.setItem('user', payload.user)
  


const actions = 
  [types.LOGIN] (context, payload) 
    return api.getToken(payload).then(response => 
      context.commit(types.LOGIN_SUCCESS, response)
      return response
    )
  


router.beforeEach((to, from, next) => 
    let user = localstorage.getItem('user')
    let token = localstorage.getItem('token')
    if (user && token) 
      store.commit(types.LOGIN_SUCCESS, token, user)
      next()
    
    else if (!store.getters.isAuthenticated) 
      store.dispatch(types.LOGIN).then(() => next())
     else 
      next()
    

【讨论】:

以上是关于在 beforeEach 期间将 vuex 模块状态传递给 vue-router的主要内容,如果未能解决你的问题,请参考以下文章

Vuex 存储在 vue-router 中未定义

在beforeAll中创建一次TestBed之后,无法在beforeEach中重置提供程序

刷新页面后Vuex无法读取属性

Nuxt + Vuex - 如何将 Vuex 模块分解为单独的文件?

将模块重构为单独的文件时,Vuex 4模块不起作用

未在实例上定义但在渲染期间引用的属性或方法 I Vuex