Vuex state on page refresh
This is a known use case. There are different solutions.
For example, one can use vuex-persistedstate
. This is a plugin for vuex
to handle and store state between page refreshes.
Sample code:
import { Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'
const store = new Store({
// ...
plugins: [
createPersistedState({
getState: (key) => Cookies.getJSON(key),
setState: (key, state) => Cookies.set(key, state, { expires: 3, secure: true })
})
]
})
What we do here is simple:
- you need to install
js-cookie
- on
getState
we try to load saved state fromCookies
- on
setState
we save our state toCookies
Docs and installation instructions: https://www.npmjs.com/package/vuex-persistedstate
Vuex: persisting state on page refresh without writing itvuex?
There are many web APIs you can use to persist some state inside your user's browsers:
- Local storage
- Indexed database
- cookies
There's also a package specifically done for that
Vuex state does not update without a page refresh
local storage isn't a reactive data so when it changes, there is no way for vuex store to get notified.
what happens is that when your app loads getToken()
is called at the very beginning and since user isn't logged in yet it returns undefined
, when user logs in, local storage is updated but getToken()
doesn't get called again.
BUT! now you have the data in your local storage so when you refresh your page manually getToken()
is called and return a Truthy
value.
what you can do is to write an action
to update accessToken
and call it when user is logged in.
something like this:
api.getToken(URL, userData).then((result) => {
// if user is logged in successfully call the action
if (result) this.$store.dispatch('auth/updateAccessToken');
})
Vue3 - Persisting state with Page refresh
You can add the created
hook to the root component by using the extends
option with the component definition:
// main.js
import { createApp } from 'vue'
import Index from './Index.vue'
import createRouter from './router'
import { createStore } from 'vuex'
import storeDefinition from './store'
const store = createStore(storeDefinition)
createApp({
extends: Index,
created() {
this.$store.dispatch('loadStoredState')
this.$store.dispatch('loadUser')
},
})
.use(createRouter())
.use(store)
.mount('#app')
demo
Vuex store empty if i refresh my webpage
To persist state data after app refresh, you can either use localStorage
or sessionStorage
.
XSS: The problems with storing tokens in
localStorage
as you say is about the app being vulnerable to XSS (cross-site-scripting) attacks. Apart from that, it is quite safe. ThelocalStorage
is bound to the domain, so the data ofwww.yourapp.com
will stay there even after the browser is closed also unlike cookies, you won't have to manage which site made the request. All the tabs on the browser with the same domain will be able to use the data in thelocalStorage
If the said behaviour is not needed, you can go for
sessionStorage
, it works almost the same way but the data gets cleared when the browser is closed.Going for cookies, sure they will help saving your token being taken away by an XSS but then you will have to ensure you also provide a
csrf-token
to protect against CSRF (Cross Site Request Forgery) attacks.If you plan on going forward with cookies, then make sure they have the
httpOnly
flag set to true in the headers, else they are no good.
Overall I have seen that localStorage has been a very commonly recommended solution for maintaining tokens and other app data.
I'll add sources to this answer for reference.
CSRF Token necessary when using Stateless(= Sessionless) Authentication?
Check the accepted answer and others as well.https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/HTML5_Security_Cheat_Sheet.md
https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage
https://www.whitehatsec.com/blog/web-storage-security/ This would let you know about the pitfalls and how-to for using localStorage.
Why can't I load data from vuex when I refresh site?
Vue is a SPA framework and SPAs doesnot support page refresh.
I recommend you to use vuex-persistedstate
npm package to prevent daa loss on page refresh.
https://www.npmjs.com/package/vuex-persistedstate
Eventhough they have stopped the supprt, this still supprts the latest version of Vue JS and VueX
Vuex store not persist 'state' when I refresh or navigate?
Vuex doesn't persist state automatically. You can use the vuex-persistedstate
package to achieve this (https://github.com/robinvdvleuten/vuex-persistedstate).
Vuex state is sometimes empty (undefined), especially when I refresh the page and sometimes it works
The getSkills
action is performing an asynchronous request. You need to wait for the request to finish before you can access this.Skills
otherwise the data will not be set yet.
You need async
and await
(the "modern" solution):
async mounted() {
await this.getSkils();
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
}
or:
mounted() {
this.getSkils().then(() => {
this.id = this.$route.params.id;
this.Skills.forEach(element => this.skill_list.push(element.skill_name));
});
}
Related Topics
Fix Node Position in D3 Force Directed Layout
Why Does JavaScript Hoist Variables
Finding Longest String in Array
How to Calculate 3D Rotation on X and Y Axis from a 4X4 Matrix
Correct Way to Handle Conditional Styling in React
Finding Element's Position Relative to the Document
How to Set a Js Object Property Name from a Variable
Order of Hoisting in JavaScript
Retrieving Binary File Content Using JavaScript, Base64 Encode It and Reverse-Decode It Using Python
Internal/Modules/Cjs/Loader.Js:582 Throw Err
How to Implement Cross Domain Url Access from an Iframe Using JavaScript
How to Sort an Array of Objects Based on the Ordering of Another Array
What Are the Semantics of Different Rxjs Subjects
Canvas Todataurl() Returns Blank Image
Es6 Iterate Over Class Methods
JavaScript Es6 Class Definition Not Accessible in Window Global