web-dev-qa-db-ja.com

beforeEach中にvuexモジュールの状態をvue-routerに渡す

VueJSをvuexおよびvue-routerと組み合わせて使用​​しています。ストアに変更を加えるvuexモジュールがあり、それを使用してユーザーが認証されているかどうかを判断しようとしています。

これが、関連する部分で私のコードがどのように見えるかです。

main.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状態を表示すると、 userauthenticatedは適切に変更されています。

[〜#〜]質問[〜#〜]

このモジュールは、ルーターが.beforeEachループで実行されているときには、単にロードされていないようです。これは本当ですか?

はいの場合、この状況に対処する方法に関する他の提案は何ですか?いいえの場合、私は何を間違っていますか?

15
The Brewmaster

console.log(store.state.core.authenticated)は、まだログインしていないため、falseを返します。

コードでは、ユーザー情報をどこにも永続化しません。例えば。 localstorageの使用

同じ考慮事項:

  1. 使用しないrouter.app.$store、インポートするstoreを使用
  2. あなたのLOGIN_SUCCESSミューテーション、ログイン情報とトークンをローカルストレージに保存
  3. 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()
    }
}
4
ridermansb