I want to show different button in Header component, based on user authentication
Header.vue
<template>
<div >
<div >
<router-link :to="{name:'login'}" v-if="!isAuth"><i ></i>Login</router-link>
<a v-if="isAuth" href="" @click.prevent="logout" :key="componentKey"><i ></i>Logout</a>
<a href="dashboard_add_listing.html" ><i ></i> Add Listing</a></div>
</div>
</template>
<script>
import {mapActions} from 'vuex'
export default {
name:"default-layout",
data(){
return {
user:this.$store.state.auth.user,
isAuth: this.$store.state.auth.authenticated,
}
},
methods:{
...mapActions({
signOut:"auth/logout"
}),
async logout() {
await axios.post('/logout').then(({data})=>{
this.signOut();
this.$parent.forceRerender();
})
},
},
}
</script>
As you can see based on the variable isAuth
which comes from the vuex state I want to show different buttons, but after logging in state doesn't change and it still show the old button (before authentication). If I refresh the page manually (f5) it shows the correct button.
Login.vue:
<script>
import { mapActions } from 'vuex'
export default {
name:"login",
data(){
return {
auth:{
email:"",
password:""
},
validationErrors:{},
processing:false
}
},
methods:{
...mapActions({
signIn:'auth/login'
}),
async login(){
this.processing = true
await axios.get('/sanctum/csrf-cookie')
await axios.post('/login',this.auth).then(({data})=>{
this.signIn()
}).catch(({response})=>{
if(response.status===422){
this.validationErrors = response.data.errors
}else{
this.validationErrors = {}
alert(response.data.message)
}
}).finally(()=>{
this.processing = false
})
},
}
}
</script>
vuex auth.js which is included in index.js vuex file:
import axios from 'axios'
import router from '@/router'
export default {
namespaced: true,
state:{
authenticated:false,
user:{}
},
getters:{
authenticated(state){
return state.authenticated
},
user(state){
return state.user
}
},
mutations:{
SET_AUTHENTICATED (state, value) {
state.authenticated = value
},
SET_USER (state, value) {
state.user = value
}
},
actions:{
login({commit}){
return axios.get('/api/user').then(({data})=>{
commit('SET_USER',data)
commit('SET_AUTHENTICATED',true)
router.push({name:'home'})
}).catch(({response:{data}})=>{
commit('SET_USER',{})
commit('SET_AUTHENTICATED',false)
})
},
logout({commit}){
commit('SET_USER',{})
commit('SET_AUTHENTICATED',false)
}
}
}
So when user logs in it enters login method in auth.js and set the correct state, here:
commit('SET_USER',data)
commit('SET_AUTHENTICATED',true)|
After that it redirects to route with name home, but Header still show old button and when I refresh the page, the correct button is displayed.
CodePudding user response:
Instead of store state isAuth: this.$store.state.auth.authenticated
try to import getters
import { mapGetters } from 'vuex'
and use getter in computed property, which is reactive, like:
computed: {
...mapGetters({ isAuth: 'auth/authenticated' }),
},