How to toggle a class on components added dynamically via computed in Vue?

Say you have a template:

<div v-for="item in items" :key="item.id">
  <p @click="toggle(item, $event)"> {{ item.name }} </p>
</div>

The items in this template come from a computed property:

computed: { ...mapGetters(['items']) }

I want to toggle a class when clicking on the <p> item (and not on it's siblings of course). Is there a simple way to go about doing this?

Is there a simple way to add a property to that individual item in the computed property and then do :class="item.prop ? 'myclass' : ''"? Preferably without having to do a dispatch just for this...

Would you instead tap on the element using $event.target, and if so, how would you toggle the class?

Upvotes: 2

Views: 1113

Answers (3)

Matt Oestreich
Matt Oestreich

Reputation: 8548

Something like this, perhaps?

HTML:

<div id="app">
  <div v-for="item in items" :key="item.id">
    <p @click="toggle($event)"> {{ item.name }}</p>
  </div>
</div>

CSS:

.my-class {
  background-color: yellow;
}

JS:

new Vue({
  el: '#app',
  data: {
    items: [{ name: "Item1", id: "1" }, { name: "Item2", id: "2" }, { name: "Item3", id: "3" }]
  },
    methods: {
    toggle($event){
        let s = $event.target.classList;
      s.contains("my-class") ? s.remove("my-class") : s.add("my-class");
    }
  }
})

Upvotes: 2

kots
kots

Reputation: 465

try this:

<div v-for="item in items" :key="item.id">
  <p @click="item.clicked=!item.clicked" 
     :class="{'class1':item.clicked, 'class2':!item.clicked}"> 
     {{ item.name }} 
  </p>
</div>

Upvotes: 0

Best I figured out so far was:

data() {
  myClasses: {}
},
methods: {
  toggle(item) {
    if (this.myClasses[item.id]) {
      this.$set(this.myClasses, item.id, false)
    } else {
      this.$set(this.myClasses, item.id, true)
    }
  }
}

And use it like this in the component:

<p @click="toggle(item)" :class="myClasses[item.id] ? 'myclass' : ''">

Upvotes: 0

Related Questions