In Vue.js, change value of specific attribute for all items in a data array

7.2k views Asked by At

I'm trying to toggle an open class on a list of items in a v-repeat. I only want one list item (the one most recently clicked) to have the class open.

The data being output has a "class" attribute which is a blank string by default. I'm using this to set the class of the list items in the v-repeat like so:

<li v-repeat="dataSet"
    v-on="click: toggleFunction(this)"
    class="{{ class }}">
    {{ itemContent }}
</li>

I'm using v-on="click: toggleFunction(this)" on each item, which lets me change the class for the specific item, but how do I change the class on all the other items?

My current on-click method:

toggleFunction: function(item) {
    if (item.class == '') {
        // code to remove the `open` class from all other items should go here.
        item.class = 'open';
    } else {
        item.class = '';
    }
}

I've tried using a regular jQuery function to strip the classes: that does remove the classes but it doesn't change the item.class attribute, so things get weird once an item gets clicked more than once...

I'm sure there must be a straightforward way to fix this that I'm not seeing, and having to set a class attribute in the data itself feels hacky anyway (but I'll settle for any fix that works).

1

There are 1 answers

1
mcallan83 On BEST ANSWER

I just ran into the same issue. I am still learning Vue, but I tackled it using the "v-class" directive. Using v-class, any time an active value is true for a record, it will automatically add the class "open" to the list element. Hope this JSFiddle helps.

<ul>
    <li 
        v-repeat="people"
        v-on="click: toggleActive(this)"
        v-class="open: active">{{ name }}
    </li>
</ul>




new Vue({
    el: '#app',
    data: {
        people: [
            {name: 'mike'},
            {name: 'joe',active: true},
            {name: 'tom'},
            {name: 'mary'}
        ]
    },
    methods: {
        toggleActive: function(person) {
            // remove active from all people
            this.people.forEach(function(person){
                person.$set('active',false);
            });
          //set active to clicked person
            person.$set('active',true);
        }
    }
});