Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid that when refreshing the page, the global status is lost with Vuex and VueRouter

I'm creating a SPA, and as a basic example of sessions on the client side, I'm using Vuex to store a boolean state if the user is logged in or not, it works fine while not manually updating the browser. As the state restarts to its initial state, is there any way to prevent this or should it always use localstorage? If so, how to get the initial state of storage?

Component Navbar

<template>
    <div>
        <ul v-if="!isLogued">
            <router-link :to="{ name:'login'}" class="nav-link">Login</router-link>
        </ul>
        <ul  v-if="isLogued">
                <a href="#" class="nav-link">Profile</a>
                <a href="" @click.prevent="logout">Salir</a>
        </ul>
    </div>
</template>
<script>
    import {mapState,mapMutations  } from 'vuex';
    export default{
        computed : mapState(['isLogued']),
        methods:{
            ...mapMutations(['logout']),
        }
    }
</script>

Store.js

export default {
    state: {
        userLogued: {},
        api_token  : '',
        isLogued : false
    },
    mutations: {

        login( state){
            state.userLogued = JSON.parse(localStorage.getItem('usuario'));
            state.api_token = localStorage.getItem('api_token');
            state.isLogued =  true
        },

        logout(state){
            state.userLogued = {}
            state.isLogued = false
            state.api_token  = null
            localStorage.clear()
        }
    }
};

App.JS

Vue.use(VueRouter)
Vue.use(Vuex)

import store from './vuex/store';
import routes from './routes';
const router = new VueRouter({
    mode: 'history',
    routes
})

const app = new Vue({
   router,
   store : new Vuex.Store(store)
}).$mount('#app')

In my login component, I do post with axios and if it is correct I do the following

   methods : {
        ...mapMutations(['login']),
        sendLogin(){
            axios.post('/api/login' , this.form)
                .then(res =>{
                    localStorage.setItem('api_token', res.data.api_token);
                    localStorage.setItem('user_logued', JSON.stringify(res.data.usuario));
                    this.login();
                    this.$router.push('/');
                })
like image 751
DarkFenix Avatar asked Apr 08 '18 05:04

DarkFenix


People also ask

How do I keep Vuex state from refreshing?

Set storage to window. localStorage and register vuexLocal. plugin as a Vuex plugin. Refresh the page and then the state will be saved to LocalStorage.

How do you update data on a page without refreshing on the Vue JS?

What you need is vm-forceUpdate. Force the Vue instance to re-render. Note it does not affect all child components, only the instance itself and child components with inserted slot content.

Is Vuex necessary in vue3?

Let's take a look at why Vuex is is still necessary, even in Vue 3. First, Vuex offers advanced debugging capabilities that Vue 3 features does not. This is a huge bonus for developers, since no one wants to spend all that time debugging! Secondly, Vuex has plugins that extend its capabilities.


1 Answers

You will need to always be using a persistent storage mechanism if you want to preserve state across page reloads, browser sessions, etc. You can use localStorage, sessionStorage, cookies, indexeddb... whichever best suits your needs, although sessionStorage is of course only good for the current session.

To restore the initial state, use a plugin for Vuex, such as vuex-peristedstate. This will take case of the saving/restoring vuex to storage for you.

For example, creating an instance of vuex-persistedstate for use in your store is as easy as:

import createPersistedState from 'vuex-persistedstate'

const store = new Vuex.Store({
  // ...
  plugins: [createPersistedState()]
})
like image 161
Brian Lee Avatar answered Sep 20 '22 19:09

Brian Lee