Issue Resolved -- Solution Provided Below
I encountered an issue in Vue2 where I was attempting to manage a v-if
and v-else
based on an @click
event within a v-for
loop. However, the v-if
did not dynamically change with each click as expected.
Below is the problematic code snippet (please note: the variable people
is sourced from a loaded store file):
<div v-for="(person, index) in people" :key="index">
<div @click="detailsOpened(index)">
<PersonIcon v-if="showDetails(index)" />
<PersonIcon2 v-else />
</div>
</div>
import {
each
} from 'lodash-es'
data(): {
return {
personMap: []
}
}
beforeMount() {
this.personMap = each(people, p => false)
}
methods: {
showDetails(index: number): boolean {
return this.personMap[index] === true
}
detailsOpened(index: number): void {
this.personMap[index] = !this.personMap[index]
}
}
Upon logging with console.log
, it appeared that the detailsOpened
method functioned correctly. The boolean value associated with each relevant index changed upon clicking the icon, ruling out any issues there. It seems that the v-if
only executes during the initial page render and does not update dynamically when values in personMap
alter. console.log
confirms that the showDetails
method runs only at the start of the page load, based on the size of the people
array. The cause of this behavior eludes me, so any guidance would be greatly appreciated!
Edit: Solution Implemented
After testing the top answer's suggestion, I encountered the console error, "Error: [vuex] do not mutate vuex store state outside mutation handlers." I transferred these methods and data to a Pinia store file and explicitly utilized "Vue.set"/"this.$set" in the store's setter, yet still received the same error. To ultimately resolve my problem, I took the following steps: 1) Transferred data and methods to a Pinia store file. 2) Employed Vue.set
in the detailsOpened
method within the store file. 3) Applied lodash's cloneDeep
on people
when initializing this.personMap
.