Good day am working on a vue project that uses both vue-router and vuex In the app whenever login is successful, I store the the JWT token in vuex. However im strugling with the following
1) Dynamically show/hide login/logoff buttons in my navbar 2) Access JWT token in vuex store when the routes changes in router.js
So basically i need access to my vuex store in my router and also how to update my navbar component when my vuex state changes (ie when login is successful)
Below is my code. I'll start with main.js
import Vue from 'vue'
import Router from 'vue-router'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import App from '../app.vue'
import router from '../router.js'
import store from '../store'
Vue.use(Router)
Vue.use(Vuetify)
const vuetify = new Vuetify
document.addEventListener('DOMContentLoaded', () => {
new Vue({
el: '#app',
router,
vuetify,
store,
render: h => h(App)
})
})
Then router.js
import Router from 'vue-router'
import Index from './views/index.vue'
import Appointments from './views/appointments.vue'
import CreateAppointment from './views/createAppointment.vue'
import Login from './views/login.vue'
import store from './store'
const router = new Router({
routes: [
{
path: '/',
name: 'root',
component: Index
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/index',
name: 'index',
component: Index
},
{
path: '/appointments',
name: 'appointments',
component: Appointments,
props: true,
meta: {
requiresAuth: true
}
},
{
path: '/create-appointment',
name: 'create-appointment',
component: CreateAppointment,
meta: {
requiresAuth: true
}
}
]
})
router.beforeEach((to, from, next) => {
if(to.matched.some(record => record.meta.requiresAuth)) {
if (store.getters.isLoggedIn) {
next()
return
}
next('/login')
} else {
next()
}
})
export default router
Then comes store which is index.js inside of store folder
import Vue from 'vue'
import Vuex from 'vuex'
import * as patient from './modules/patient.js'
import * as appointment from './modules/appointment.js'
import * as user from './modules/user.js'
import * as notification from './modules/notification.js'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
modules: {
user,
patient,
appointment,
notification
}
})
And lastly is my nabar.vue component which is nested in App.vue. Ps i have taken out navigation drawer and bottom navigation to lessen the code.
<template>
<nav>
<v-app-bar app dark>
<v-btn text rounded dark v-on:click='showDrawer = !showDrawer'>
<v-icon class='grey--text' left>menu</v-icon>
</v-btn>
<v-toolbar-title d-sm-none>
<span class='font-weight-light'>SASSA</span>
</v-toolbar-title>
<v-spacer></v-spacer>
<!-- Log in button -->
<v-btn text rounded dark v-on:click='login' v-show='!isLoggedIn'>
<span>Login</span>
<v-icon class='grey--text' right>arrow_forward</v-icon>
</v-btn>
<!-- Log out button -->
<v-btn text rounded dark v-on:click='logout' v-show='isLoggedIn'>
<span>Logout</span>
<v-icon class='grey--text' right>exit_to_app</v-icon>
</v-btn>
</v-app-bar>
</nav>
</template>
<script>
import { mapState } from 'vuex'
export default {
data(){
return {
activeBtn: 1,
showDrawer: false,
links: [
{ title: 'Appointments', icon: 'calendar_today', link: '/appointments'},
{ title: 'New Appointment', icon: 'event', link: '/create-appointment'}
]
}
},
computed: {
isLoggedIn() {
var result = (this.$store.getters['isLoggedIn'] == "true")
return result
},
...mapState(['user'])
},
methods: {
logout() {
this.$store.dispatch('user/logout')
.then(() => {
this.$router.push('/login')
})
},
login() {
this.$router.push('/login')
}
}
}
</script>
This is where i try to access store in router
if (store.getters.isLoggedIn) {
Any help would be highly appreciated
Below is the user.js module
import AxiosService from '../services/AxiosService.js'
export const namespaced = true
export const state = {
status: '',
token: '',
user: {}
}
export const mutations = {
AUTH_SUCCESS(state, payload){
state.status = 'logged_on'
state.token = payload.token
state.user = payload.user
},
LOGG_OFF(state){
state.status = 'logged_off'
state.token = ''
state.user = {}
}
}
export const actions = {
login({commit, dispatch}, user){
return AxiosService.logon(user)
.then(response => {
const token = response.data.auth_token
const user = response.data.user
localStorage.setItem('token',token)
commit('AUTH_SUCCESS', {token, user})
})
.catch(error => {
const notification = {
type: 'error',
message: 'Invalid Credentials !!!'
}
dispatch('notification/add', notification, { root: true})
throw error
})
},
logout({commit}){
localStorage.setItem('token','')
commit('LOGG_OFF')
}
}
export const getters = {
isLoggedIn: state => !!state.token,
authStatus: state => state.status,
getUser: state => state.user
}
isLoggedIn
in template like you do. Does it not work? – Estus FlaskisLoggedIn
. Could you share the module? – ellisdod