Garfonzo
Garfonzo

Reputation: 3966

VueJS - how to watch a value in localStorage?

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

Answers (4)

arve0
arve0

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

  1. adds a mixin to make initialState available in all Vue instances, and
  2. watches for changes and stores them.

Disclaimer: I'm the author of vue-persistent-state.

Upvotes: 0

For the Name
For the Name

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

Salam
Salam

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

Mario Lamacchia
Mario Lamacchia

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

Related Questions