Vue Components
Actions
State
Mutations
Backend API
Devtools
Dispatch
Commit
Mutate
Render
Vuex
single source of truth for store state
similar to mutations but it commits mutations
the only way to change store state
to compute derived state based on store state.
(is cached)
(can only be sync)
(can be async)
Restocking...
40
const store = new Vuex.Store({
state: {
supply: 40
},
actions: {
restock(context) {
return context.commit('restock')
}
},
getters: {},
mutations: {
restock(state) {
state.supply--
}
}
})
new Vue({
el: "#vue",
computed: {
stock() {
return $store.state.supply
}
},
data() {
return {
stock: 40
}
},
methods: {
...
restock() {
$store.dispatch('restock')
}
},
template: `
<div>
<p class="supply">{{ supply }}</p>
<div class="actions">
<button @click="dispense">+</button>
<button @click="restock">-</button>
</div>
</div>
`,
})
fetchFromInventory
stockItems
Let's rename!
const store = new Vuex.Store({
state: {
supply: 30
},
actions: {
fetchFromInventory(context) {
// make API Call
// on successful return, mutate
// i.e. context.commit("stockItems")
}
},
getters: {},
mutations: {
stockItems(state) {
// update supply
}
}
})
new Vue({
el: "#vue",
computed: {
supply() {
return $store.state.supply
}
},
methods: {
...
restock() {
$store.dispatch('fetchFromInventory')
}
},
template: `
<div>
<p class="supply">{{ supply }}</p>
<div class="actions">
<button @click="dispense">+</button>
<button @click="restock">-</button>
</div>
</div>
`,
})
// fake out API //
let inventory = {
"chips": {
stock: 40
}
}
var pingInventory = function(item) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(inventory[item]);
}, 3000);
});
}
const store = new Vuex.Store({
state: {
supply: 30
},
actions: {
fetchFromInventory(context) {
pingInventory("chips")
.then(inventory => {
context.commit('stockItems', inventory.stock)
})
}
},
getters: {},
mutations: {
stockItems(state) {
// update supply
}
}
})
new Vue({
el: "#vue",
computed: {
supply() {
return $store.state.supply
}
},
methods: {
...
restock() {
$store.dispatch('fetchFromInventory')
}
},
template: `
<div>
<p class="supply">{{ supply }}</p>
<div class="actions">
<button @click="dispense">+</button>
<button @click="restock">-</button>
</div>
</div>
`,
})
fake out an API
call fake API
...
var pingInventory = function(item) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(inventory[item]);
}, 3000);
});
}
const store = new Vuex.Store({
state: {
supply: 30
},
actions: {
fetchFromInventory(context) {
pingInventory("chips")
.then(inventory => {
context.commit('stockItems', inventory.stock)
})
}
},
getters: {},
mutations: {
stockItems(state payload) {
state.supply = payload
}
}
})
new Vue({
el: "#vue",
computed: {
supply() {
return this.$store.state.supply
}
},
methods: {
...
restock() {
this.$store.dispatch('fetchFromInventory')
}
},
template: `
<div>
<p class="supply">{{ supply }}</p>
<div class="actions">
<button @click="dispense">+</button>
<button @click="restock">-</button>
</div>
</div>
`,
})
// fake out API //
let inventory = {
"chips": {
stock: 40
}
}
var pingInventory = function(item) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(inventory[item]);
}, 3000);
});
}
const store = new Vuex.Store({
state: {
supply: 30,
isRestocking: false
},
actions: {
fetchFromInventory(context) {
context.commit('isRestocking', true)
pingInventory("chips")
.then(inventory => {
context.commit('stockItems', inventory.stock)
})
.finally(() => {
context.commit('isRestocking', false)
})
}
},
getters: {},
mutations: {
stockItems(state) {
// update supply
},
isRestocking(state, payload) {
state.isRestocking = payload;
}
}
})
new Vue({
el: "#vue",
computed: {
supply() {
return this.$store.state.supply
},
isRestocking() {
return this.$store.state.isRestocking
}
},
methods: {
...
restock() {
$store.dispatch('fetchFromInventory')
}
},
template: `
<div>
<p class="supply">{{ supply }}</p>
<div class="actions">
<button @click="dispense">+</button>
<button @click="restock">-</button>
</div>
</div>
`,
})
create a loading state
https://codepen.io/shortdiv/pen/xxGrMLV
Let's create isRestocking state in Vuex that gets toggled on fetchInventory
Dispensing...
6
// fake out API //
let inventory = {
"chips": {
stock: 40
}
}
var pingInventory = function(item) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(inventory[item]);
}, 3000);
});
}
const store = new Vuex.Store({
state: {
supply: 30,
isRestocking: false
},
actions: {
fetchFromInventory(context) {
context.commit('isRestocking', true)
pingInventory("chips")
.then(inventory => {
context.commit('stockItems', inventory.stock)
})
.finally(() => {
context.commit('isRestocking', false)
})
}
},
getters: {},
mutations: {
stockItems(state) {
// update supply
},
isRestocking(state, payload) {
state.isRestocking = payload;
}
}
})
new Vue({
el: "#vue",
computed: {
supply() {
return this.$store.state.supply
},
isRestocking() {
return this.$store.state.isRestocking
}
},
methods: {
...
restock() {
$store.dispatch('fetchFromInventory')
}
},
template: `
<div>
<p class="supply">{{ supply }}</p>
<div class="actions">
<button @click="dispense">+</button>
<button @click="restock">-</button>
</div>
</div>
`,
})
single source of truth for store state
similar to mutations but it commits mutations
the only way to change store state
to compute derived state based on store state.
(is cached)
(can only be sync)
(can be async)
const store = new Vuex.Store({
state: {
supply: 40,
...
},
actions: {
fetchFromInventory(context) {
...
context.commit('stockItems', stock.inventory)
}
},
getters: {
isSupplyLow: state => state.supply < 10
},
mutations: {
stockItems(state, payload) {
state.supply = 40
},
...
}
})
new Vue({
el: "#vue",
computed: {
supply() {
return this.$store.state.supply
},
isSupplyLow() {
return this.$store.getters.isSupplyLow
}
},
methods: {
...
restock() {
$store.dispatch('fetchFromInventory')
}
},
template: `
<div>
<p class="supply">{{ supply }}</p>
<div class="actions">
<button @click="dispense">+</button>
<button @click="restock">-</button>
</div>
</div>
`,
})
ES
EN
Switch out the logic to switch language so it's handled in a Vuex getter