简体   繁体   中英

Vuex state doesn't change after login / logout

I want to show different button in Header component, based on user authentication

Header.vue

<template>
        <div class="utf_right_side">
          <div class="header_widget">
            <router-link :to="{name:'login'}" class="button border sign-in popup-with-zoom-anim" v-if="!isAuth"><i class="fa fa-sign-in"></i>Login</router-link>
            <a class="button border sign-in popup-with-zoom-anim" v-if="isAuth" href="" @click.prevent="logout" :key="componentKey"><i class="fa fa-sign-in"></i>Logout</a>
            <a href="dashboard_add_listing.html" class="button border with-icon"><i class="sl sl-icon-user"></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.

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' }),
 },

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM