2
votes

I try to store drawer data in VueX to use it on external component.

My console error: [vuex] unknown action type: app/switchDrawer

My VueJS template:

pages/test.vue

<template>
  <v-navigation-drawer v-model="drawer" app>
    <v-list dense>
      ...
    </v-list>
  </v-navigation-drawer>
</template>

<script>
export default {
  computed: {
    drawer: {
      get () {
        return this.$store.state.app.drawer
      },
      set (value) {
        console.log(value);
        return this.$store.dispatch('app/toggleDrawer', value)
      }
    }
  }
}
</script>

The console.log() function give me lot of lines in loop in console.

I'd like to use too the mapGetters class from VueX instead computed get/set:

computed: mapGetters({
  drawer: 'app/drawer'
})

I've an error in console:

[Vue warn]: Computed property "drawer" was assigned to but it has no setter.

My VueX store:

store/app.js

export const state = () => ({
  drawer: true
})

export const getters = {
  drawer: state => state.drawer
}

export const mutations = {
  TOGGLE_DRAWER: (state) => {
    state.drawer = !state.drawer
  }
}

export const actions = {
  toggleDrawer ({ commit }, value) {
    commit('TOGGLE_DRAWER', value)
  }
}
2
Are your modules namespaced? If not then mapping works a bit diffrently computed: { ...mapState({ drawer: state => state.FilenameOfYourModule.drawer })}. The other issue might be the diffrent naming of your mutations and getters - I name them exactly the same - but it's only a warning after all.Hexodus
@Hexodus With this method, I get this error: Computed property "drawer" was assigned to but it has no setter.pirmax
Well my bad, it's not to be used for two way binding - have overlooked that you need a setter too.Hexodus

2 Answers

0
votes

Found your problem - a computed setter has to have no return statement.

 drawer: {
      get () {
        return this.$store.state.app.drawer
      },
      set (value) {
        this.$store.dispatch('app/toggleDrawer', value)
      }
    }

Please notice that your action submits a value to the mutation which dosen't take any value. So better add a new mutation that handles said value:

export const mutations = {
  SET_DRAWER: (state, value) => {
    state.drawer = value
  }
}

export const actions = {
  toggleDrawer ({ commit }, value) {
    commit('SET_DRAWER', value)
  }
}
1
votes

IN CASE YOU DON'T WANT TO MAKE A NEW MUTATION AND HANDLE LOCALLY. (which I preferred personally as my store is pretty big already)

Faced similar issue using when using a vue-ui library(vuesax)

Solved it by initializing a new data variable to a computed variable (the one from the store) in created hook (Why in created hook)

   created() {
      this.localDrawer = this.drawer
   },
   data() {
      return {
         localDrawer: ''
      }
   },
   computed: {
      ...mapGetters({
         drawer: 'drawer'
      })
   },
   watch: {
      drawer(newValue, oldValue) {
         this.localDrawer = newValue
      }
   }

Now use localDrawer in the you app. NOTE: I am watching the drawer variable as well. So that in any case if its value changes it gets reflected.