1

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)
   }
  } 
})
1
  • Just found my error. There should be as follows: <component v-bind:is="this.$store.state.currentView"></component> Commented Oct 29, 2016 at 22:20

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.