Reputation: 3966
I have a nav
component that needs to only be shown when there is a token stored in localStorage
. When that token is deleted from localStorage
the nav
component needs to notice that change and hide itself.
What's the best way to approach this?
Upvotes: 3
Views: 23487
Reputation: 3647
Assuming you are setting the token yourself, store the token in a global state and persist it with vue-persistent-state. The plugin is suitable for simple apps, where state management with vuex is not needed.
For example
import persistentStorage from 'vue-persistent-storage';
const initialState = {
token: 0 // overwritten if found in localStorage
};
Vue.use(persistentStorage, initialState);
new Vue({
data: {
sections: ['Home', 'Edit']
// we get `token` from persistentStorage
},
template: `<nav>
<a
v-for="(section, i) in sections"
class="{ active: token === i }"
>
{{section}}
</a>
</nav>`,
methods: {
changeToken: function () {
// you may change token from other Vue instances too
this.token = this.token++
// wrap
this.token = this.token % this.sections.length
}
}
})
token
is available as data in all components and Vue instances. Any changes to this.token
will be stored in localStorage, and you can use this.token
as you would in a vanilla Vue app.
The plugin is basically watcher and localStorage.set
. You can read the code here. It
initialState
available in all Vue instances, andDisclaimer: I'm the author of vue-persistent-state.
Upvotes: 0
Reputation: 2529
Local Storage is not reactive, so you need to store your token in some place that is. I assume your token is being set and deleted by the application. If so, the best way to handle this is to use state like Vuex (see Vue State Management).
Option 1
If you are using local storage in order to retain the token between multiple browser sessions, the best option is to just set the token in Vuex then use Vuex persisted state to sync Vuex to local or session storage. The plugin will retrieve it again when you need to re-establish state.
Option 2
If you need it set in the local storage directly, you should include in your mutations to set/unset the localStorage when you are changing the state. This will keep your localStorage and State in sync.
For example using Vuex, if you are receiving a token in a response you can then call a Mutation to set it in Vuex state as well as set it to localStorage:
SET_TOKEN(state, payload){
state.token = payload.token
localStorage.setItem('token', payload.token)
}
You can then easily watch the Vuex state. Depending on how your Vuex is set up, it may be something like: this.$store.state.token
Upvotes: 10
Reputation: 1168
Using CustomEvent
and listening to it can help you make localStorage "reactive", answered in similar question here https://stackoverflow.com/a/61178486/6714319
Upvotes: 0
Reputation: 1723
Hiding your navbar should not be related with setting localStorage. I would expect something like this:
function hideNav() {
// Inform the application that the nav should hide
dispatchHideNavAction()
// Change localStorage
deleteTokenFromLocalStorage()
}
If instead, your problem is in hiding the nav when the token is deleted from another window, then you can use StorageEvent:
window.addEventListener('storage', (e) => {
if (e.key === 'mytoken' && e.newValue === null) {
hideNav()
}
});
NB: this won't work within the same window, but only if the token is deleted from another tab.
Upvotes: 1