Search code examples
typescriptvue.jsv-forvue-class-components

Vue v-for not updating, even with set


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


Solution

  • 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.