I am trying to watch for changes in a state in vuex. The state is an array. I am changing the values of that array with the press of a button. Whenever i press that button and the array (vuex state) changes i want to display the values in a list on the screen.
This is the main vuex store:
import { createStore } from 'vuex';
import rollingModule from './modules/rolling/index.js';
const store = createStore({
modules: {
rolling: rollingModule,
},
});
export default store;
This is my vuex store module:
export default {
namespaced: true,
state() {
return {
numbers: [0, 0, 0, 0, 0],
};
},
mutations: {
rollDice(state, payload) {
state.numbers = payload;
},
},
actions: {
rollDice(context) {
const rolledNumbers = [];
for (let i = 0; i < 5; i++) {
rolledNumbers.push(Math.floor(Math.random() * 7));
}
context.commit('rollDice', rolledNumbers);
},
},
getters: {
getNumbers: (state) => state.numbers,
},
};
My first attempt was using a computed property to react to changes but that doesnt seem to be working. I have then added a watcher for that computed property to console.log the old and new values but the watcher seems to never get fired.
Heres my component code:
<template>
<ul>
<li v-for="number in rolledNumbers" :key="number">
{{ number }}
</li>
</ul>
</template>
<script setup>
import { computed, watch } from 'vue';
import { useStore } from 'vuex';
const store = useStore();
const rolledNumbers = computed(() => {
store.getters['rolling/getNumbers'];
});
watch(rolledNumbers, (newValue, oldValue) => {
console.log('Old Array: ' + oldValue);
console.log('New Array: ' + newValue);
});
</script>
I've read something about deep watchers to watch for changes to the values of the arrays but i couldn't find anything good for the composition api and .
EDIT 1: My watcher now fires when the nested elements change. This is the code for that:
watch(
rolledNumbers,
(newValue, oldValue) => {
console.log('Old Array: ' + oldValue);
console.log('New Array: ' + newValue);
},
{ deep: true }
);
Unfortunately oldValue and newValue both return undefined.
Your mutation is replacing the array in numbers
with a completely new array. This means that the reference to the array is lost, breaking the reactivity:
rollDice(state, payload) {
state.numbers = payload;
}
You need to replace the contents of the array in order for the references to be preserved. You could do something like:
rollDice(state, payload) {
# Remove all items from the array
state.numbers.length = 0
# Fill the array with the items from the payload array
[].push.apply(state.numbers, payload)
}