Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sync states between backend and frontend using vuex and vue-router?

I am developing a single-page-application using vue-cli3 and npm.

The problem: Populating a basic integer value (stored in a vuex state) named counter which was incremented/decremented in the backend to the frontend, which displays the new value.

The increment/decrement mutations are working fine on both components (Frontend/Backend), but it seems like the mutations don't work on the same route instance: When incrementing/ decrementing the counter in backend, the value is not updated in the frontend and otherwise.

store.js:

Contains the state which needs to be synced between Backend/Frontend.

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    counter: 10
  },
  mutations: {
    increment (state) {
      state.counter++
    },
    decrement (state) {
      state.counter--
    }
  }
})

index.js:

Defines the routes that the vue-router has to provide.

import Vue from 'vue'
import Router from 'vue-router'
import Frontend from '@/components/Frontend'
import Backend from '@/components/Backend'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Frontend',
      component: Frontend
    },
    {
      path: '/backend',
      name: 'Backend',
      component: Backend
    }
  ],
  mode: 'history'
})

main.js:

Inits the Vue instance and provides the global store and router instances.

import Vue from 'vue'
import App from './App'
import router from './router'
import { sync } from 'vuex-router-sync'
import store from './store/store'

Vue.config.productionTip = false

sync(store, router)

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

Frontend.vue/Backend.vue:

Both (Frontend/Backend) use the same code here. They use the state counter in order to display and modify it.

<template>
  <div> Counter: {{ getCounter }}
    <br>
    <p>
      <button @click="increment">+</button>
      <button @click="decrement">-</button>
    </p>
  </div>
</template>

<script>
export default {
  name: 'Frontend',
  methods: {
    increment () {
      this.$store.commit('increment')
    },
    decrement () {
      this.$store.commit('decrement')
    }
  },
  computed: {
    getCounter () {
      return this.$store.state.counter
    }
  }
}
</script>

It would be awesome if someone sould tell me what I am missing or if I have misunderstood the concept of vuex and vue-router.

like image 440
sebikolon Avatar asked Mar 22 '19 14:03

sebikolon


1 Answers

Just get the counter from the store for both components. You don't need data as store is already reactive.

<template>
  <div> Counter: {{ counter }}
    <br>
    <p>
      <button @click="increment">+</button>
      <button @click="decrement">-</button>
    </p>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
  name: 'Frontend',
  methods: {
    ...mapMutations([
      'increment',
      'decrement',
    ])
  },
  computed: {
    ...mapState({
        counter: state => state.counter,
    })
  }
}
</script>

For reference:

  • mapState: https://vuex.vuejs.org/guide/state.html#the-mapstate-helper
  • mapMutations: https://vuex.vuejs.org/guide/mutations.html#committing-mutations-in-components
like image 115
R3ctor Avatar answered Nov 22 '22 11:11

R3ctor