For a hangman game I have a Word.vue
component in which I'm trying to initialise an array named wordToGuessAsArray
containing n empty items (n = number of letters in word to guess):
<template>
<section>
<div v-for="(letter, i) in wordToGuessAsArray" :key="i">
</div>
</section>
</template>
<script>
export default {
computed: {
wordToGuessAsArray () {
return this.$store.state.wordToGuessAsArray
}
},
mounted () {
const wordToGuess = 'strawberry'
for (var i = 0; i < wordToGuess.length; i++) {
this.$store.commit('SET_WORD_AS_ARRAY_PUSH')
}
}
}
</script>
Below is the content of my store
relevant to this question:
state: {
wordToGuessAsArray: [],
},
mutations: {
SET_WORD_AS_ARRAY_PUSH (state) {
state.wordToGuessAsArray.push('')
},
SET_WORD_AS_ARRAY (state, value) {
state.wordToGuessAsArray[value.i] = value.letter
}
}
My problem is the following. In my Keyboard.vue
component, when user picks a letter that does indeed belong to the word to guess, I update my state thus:
this.$store.commit('SET_WORD_AS_ARRAY', { letter, i })
I expect this mutation to update the word in my Word.vue
component here:
<div v-for="(letter, i) in wordToGuessAsArray" :key="i">
Yet it doesn't. wordToGuessAsArray
seems non reactive, why?
It is because state.wordToGuessAsArray[value.i] = value.letter
is not reactive.
Because Vue.js only watch array methods like push
or splice
.
You need to do this.$set(state.wordToGuessAsArray, value.i, value.letter);
Or in Vuex :
Vue.set(state.wordToGuessAsArray, value.i, value.letter);
and import Vue in your file.
Read more here :
https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats