1
votes

I build SPA using VueJs + VueX and I have buttons "Login" and "Sign Up" to be clicked in one component and <component></component> tag in other component where should be conditionally rendered 1 of to Modals ("SignUp" form and "Login form"). Modals are also components.
When I call console.log, I see that state.currentView changes depending which button clicked but checking {{ $data | json }} inside markup shows that state wasn't changed and what is more important the modal are not changing. So I've code as follows:

App.vue:

<template>
  <navbar></navbar>
  <component v-bind:is="currentView"></component>
</template>

<script>
 import Login from './components/Login'
 import Signup from './components/Signup'
 import Navbar from './components/Navbar'
 import NavbarInner from './components/NavbarInner'

 import store from './vuex/store'

 export default {
 name: 'app',
 data () {
   return {
     currentView: this.$store.state.currentView
   }
 },
 components: {
   Login,
   Signup,
   Navbar,
 },
 store
}
</script>

In Navbar.vue template I keep the buttons and methods to change currentView state:

    <md-button class="navbar__link"
               @click="changeCurrentModal('Signup')">
      Sign Up
    </md-button>

    <md-button class="navbar__link"
               @click="changeCurrentModal('Login')">
      Login
    </md-button>

    export default {
     name: 'navbar',
     computed: {
       currentView () {
        return this.$store.state.currentView
      }
    },
    methods: {
      changeCurrentModal (curentView) {
        this.$store.commit('changeCurrentModal', curentView)
     }
   }
 }
 </script>

My store.js file looks as follows:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
state: {
  currentView: 'Signup'
},
mutations: {
  changeCurrentModal: (state, currentView) => {
    console.log(currentView)
    state.currentView = currentView
  }
},
actions: {
   changeCurrentModal: ({commit}, currentView) => {
     commit('changeCurrentModal', currentView)
   }
  } 
})
2
Just found my error. There should be as follows: <component v-bind:is="this.$store.state.currentView"></component>Evgeny Ladyzhenskiy

2 Answers

0
votes

Although you got Vuex to work, you may want to check out Vue-router if you haven't already. It would accomplish the same thing you want and might offer code that's easier to follow.

0
votes

What you should do is make a getter and pull it into your component using a computed property.

Your vuex would become...

...

export default new Vuex.Store({
   state: {
      currentView: 'Signup'
   },
   getters: {
      getCurrentView: state => {
          return state.currentView
      }
   }
   mutations: {
      ...
   },
   actions: {
      ...
   }
})

And your computed prop would look like this...

computed: {
  currentView () {
    return this.$store.getters.getCurrentView
  }
}

By doing this, you will maintain reactivity with vuex data.