I have a v-for
list that renders the initial state of an array. But when I add items to the array, the rendering is not updated.
Most answers in the docs and here on SO mention you have to use this.$set
instead of array.push()
, but in my case that isn't helping.
When calling addTag("thing")
, "thing" is added to the array and it is visible in the Vue inspector. It's just the v-for
that isn't updated.
template
<span v-for="(tag, index) in project.tags" :key="index">
{{tag}} // this renders all the tags that are initially available
</span>
code (vue typescript class template)
export default class Student extends Vue {
project:Project = {} as Project
newtag : string = ""
addTag() {
// adds to array, but v-for not updating
this.$set(this.project.tags, this.project.tags.length, this.newtag)
// adds to array, but v-for not updating
this.project.tags.push(this.newtag)
}
}
EDIT this code uses the typescript class component
You only need to use $set when you want to add an attribute to an object after initialization, instead of using it here, just init the object with an empty tag array.
Change your code to look like this:
export default class Student extends Vue {
//I'm not a TS expert, so I'm not sure this is the correct way to init
// a tags array, but you get the point
project:Project = {tags:[]} as Project
newtag : string = ""
addTag() {
// adds to array, but v-for not updating
this.project.tags.push(this.newtag)
}
}
As a side note, if you are planning on changing the list dynamically (adding/removing tags), using the index as a key is not recommended and can lead to unexpected behavior. Better use an id or the tag name if it's unique.