Getting Vuex State into SFCs

Isolating Vuex

const store = new Vuex.Store({
  state: {
    supply: 40
  },
  actions: {},
  getters: {
    isSupplyLow: state => state.supply < 10
  },
  mutations: {}
})

new Vue({
  el: "#vue",
  store: store,
  computed: {
    supply() {
      return this.$store.state.supply
    },
    isStockLow() {
      return this.$store.getters.isSupplyLow
    }
  },
  methods: {
    ...
  },
  template: `
    <div>
      <p class="supply">{{ supply }}</p>
      <div class="actions">
        <button @click="dispense">+</button>
        <button @click="restock">-</button>
      </div>
    </div>
  `,
})
├── src/
  ├── components
  ├── App.vue
  ├── main.js
  └── store.js
├── ...
└── public/
main.js
store.js

Vuex Folder Structure

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {}
});

store.js

import Vue from "vue";
import App from "./App.vue";
import store from "./store";

Vue.config.productionTip = false;

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

main.js

Let's move our vuex store into a separate file

Exercise Time!

[step-0]

https://github.com/shortdiv/vuex-sfc

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  getters: {},
  state: {
    stock: 30,
  },
  mutations: {},
  actions: {
    fetchFromInventory(context) {
      context.commit('restock')
    }
  },
  mutations: {
    restock(state) {
      state.stock = 30
    }
  }
})

 - context.state

 - context.commit

 - context.getters

 - context.dispatch

{
  state,
  commit,
  getters,
  dispatch
}
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  getters: {},
  state: {
    stock: 30,
  },
  mutations: {},
  actions: {
    fetchFromInventory({ commit }) {
      commit('restock')
    }
  },
  mutations: {
    restock(state) {
      state.stock = 30
    }
  }
})

300

210

130

0

restock

Determine how much to restock

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  getters: {},
  state: {
    stock: 30,
  },
  mutations: {},
  actions: {
    fetchFromInventory({ commit }) {
      API_CALLING()
        .then(result => {
          commit('restock', result.json())
        })
    }
  },
  mutations: {
    restock(state) {
      state.stock = 30
    }
  }
})

using API payloads

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  getters: {},
  state: {
    stock: 30,
  },
  mutations: {},
  actions: {
    fetchFromInventory({ commit }) {
      API_CALLING()
        .then(result => {
          commit('restock', result.json())
        })
    }
  },
  mutations: {
    restock(state, payload) {
      state.stock = payload
    }
  }
})

passing the payload to mutation

Destructure context so it uses the methods commit and dispatch

Exercise Time!

[step-1]

https://github.com/shortdiv/vuex-sfc

Vuex Helpers

<template>
  <div>
    <p class="stock">{{ stock }}</p>
    <div class="actions">
      <button @click="dispense">+</button>
      <button @click="restock">-</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "VendingMachine",
  computed: {
    stock() {
      return this.$store.state.stock
    },
    isStockLow() {
      return this.$store.getters.isStockLow
    }
  },
  methods: {
    restock() {
      this.$store.dispatch("fetchFromInventory");
    },
    dispense() {
      this.$store.dispatch("dispenseFromStock")
    }
  }
}
</script>
import { 
  mapState,
  mapActions,
  mapGetters,
  mapMutations
} from "vuex"
<template>
  <div>
    <p class="stock">{{ stock }}</p>
    <div class="actions">
      <button @click="dispense">+</button>
      <button @click="restock">-</button>
    </div>
  </div>
</template>

<script>
import { mapState } from "vuex";

export default {
  name: "VendingMachine",
  computed: {
    ...mapState(["stock"]),
    stock() {
      return this.$store.state.stock
    }
    isStockLow() {
      return this.$store.getters.isStockLow
    }
  },
  methods: {
    restock() {
      this.$store.dispatch("fetchFromInventory");
    },
    dispense() {
      this.$store.dispatch("dispenseFromStock")
    }
  }
}
</script>
<template>
  <div>
    <p class="stock">{{ stock }}</p>
    <div class="actions">
      <button @click="dispense">+</button>
      <button @click="restock">-</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapActions } from "vuex";

export default {
  name: "VendingMachine",
  computed: {
    ...mapState(["stock"]),
    isStockLow() {
      return this.$store.getters.isStockLow
    }
  },
  methods: {
    ...mapActions(["fetchFromInventory"]),
    restock() {
      this.$store.dispatch("fetchFromInventory");
    },
    dispense() {
      this.$store.dispatch("dispenseFromStock")
    }
  }
}
</script>

this.fetchFromInventory()

<template>
  <div>
    <p class="stock">{{ stock }}</p>
    <div class="actions">
      <button @click="dispense">+</button>
      <button @click="restock">-</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapActions } from "vuex";

export default {
  name: "VendingMachine",
  computed: {
    ...mapState(["stock"]),
    isStockLow() {
      return this.$store.getters.isStockLow
    }
  },
  methods: {
    ...mapActions({ restockItem: "fetchFromInventory" }),
    restock() {
      this.$store.dispatch("fetchFromInventory");
    },
    dispense() {
      this.$store.dispatch("dispenseFromStock")
    }
  }
}
</script>

this.restockItem()

Update so that the remaining action and getters are using helpers

Exercise Time!

[step-2]

https://github.com/shortdiv/vuex-sfc

Vuex Helpers

By shortdiv

Vuex Helpers

  • 1,015