Search code examples
vue.jsvuexnuxt.jscomputed-properties

Computed property depends on vuex store. How to update the cached value?


The value of this.$store.state.Auth.loginToken is modified by one of its child components. The initial value of this.$store.state.Auth.loginToken is undefined. But still, the update in its value has no effect in the cached value of navItems thus it always returns the second value.

computed: {
    navItems () {
        return this.$store.state.Auth.loginToken != undefined ?
        this.items.concat([
            { icon: 'add', title: 'Add new journal entry', to: '/' },
            { icon: 'power_settings_new', title: 'Logout', to: '/logout'}
        ]) :
        this.items.concat([
            { icon: 'play_arrow', title: 'Login', to: '/login' }
        ])
    }
}

Is there a better way to keep a watch on this.$store.state.Auth.loginToken so that it can be used same as navItems?


Solution

  • I created a basic example of how you can use vuex getters and Auth token (codepen):

    const mapGetters = Vuex.mapGetters;
    
    var store = new Vuex.Store({
      state: {
        Auth: {
          loginToken: ''
        },
        menuItems: [
           { icon: 'home', title: 'Home', to: '/' },
           { icon: 'about', title: 'About', to: '/about' },
           { icon: 'contact', title: 'Contact', to: '/contact' }
        ]
      },
      mutations: {
        SET_LOGIN_TOKEN(state, data) {
          state.Auth.loginToken = 1
        }
      },
      getters: {
        menuItems(state, getters) {
          if(state.Auth.loginToken !== '') {
            return state.menuItems.concat([{
                icon: 'profile', title: 'Profile', to: '/profile'
            }])
          }
          return state.menuItems
        },
        loggedIn(state) {
          return state.Auth.loginToken !== ''
        }
      },
      actions: {
        doLogin({commit}) {
           commit('SET_LOGIN_TOKEN', 1)
        }
      }
    });
    
    new Vue({
      el: '#app',
      store,
      data: function() {
        return {
          newTodoText: "",
          doneFilter: false
        }
      },
      methods: {
        login() {
           this.$store.dispatch('doLogin')
        }
      },
      computed: {
       ...mapGetters(['menuItems', 'loggedIn'])
      }
    })
    

    This is just an example so you can ignore the actual login action. Also, the store should be a directory, the getters, mutations and actions should have their own files which are then imported in the index.js in the store like in this example