Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Toggle inside v-for items affects the entire list, how can I make the each toggle affect only the containing list item?

I'm making a list of items with v-for loop. Inside each item of the loop there is button with click event method that showing description text. When i click on the button, it should toggle only inside it's own item, but it affecting all elements in v-for list.

So, how to make a toggle method that will affect only it's own item?

<template>
  <div>

    <div v-for="item in items" :class="{ activeclass: isActive }">

      <div class="item-text">
        {{item.text}}
      </div>
      <button @click="toggle()">show</button>

      <div v-show="isActive" class="item-desc">
        {{item.desc}}
      </div>

    </div>


  </div>
</template>

<script>
  export default {

    data () {

      return {

        items: [
          {
            text: 'Foo',
            desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
          },
          {
            text: 'Bar',
            desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',

          }
        ],

        isActive: false
      }
    },

    methods: {

      toggle: function () {
        this.isActive = !this.isActive;
      }

    },


  }
</script>
like image 980
Roslan Elyashiv Avatar asked Jan 08 '17 11:01

Roslan Elyashiv


1 Answers

As @Nora said you can (and probably should) create a separate component for each list item, so you would have a component that accepts an item as a prop, then each component can have it's own isActive flag, which keeps the markup nice and clean:

Component:

Vue.component('toggle-list-item', {
  template: '#list-item',
  props: ['item'],
  methods: {
    toggle() {
      this.isActive = !this.isActive;
    }
  },
  data() {
    return {
      isActive: false
    }
  },
})

Markup

Now you can simply place the component inside your v-for:

<div id="app">
  <div v-for="item in items">
    <toggle-list-item :item="item"></toggle-list-item>
  </div>
</div>

Here's the JSFiddle: https://jsfiddle.net/w10qx0dv/

like image 136
craig_h Avatar answered Oct 29 '22 13:10

craig_h