-1

So I have a small Vue.js project that displays 6 objects of "Ninjas" and when I click on the button toggle it suppose to toggle the "ninja's speciality":

<template>
  <div id="ninjas">
  <ul>
    <li v-for="x in ninjas">
      <h1>{{x.name}}</h1>
      <h2 v-show="x.show">{{x.speciality}}</h2>
      <button v-on:click="toggle(x.show)">Toggle</button>
    </li>
  </ul>
  </div>
</template>

<script>
    export default {
        name: "main",
      data() {
          return {
            ninjas: [
              {name: 'Ryu', speciality: 'Vue Components', show: false},
              {name: 'Crystal', speciality: 'HTML Wizardry', show: false},
              {name: 'Hitoshi', speciality: 'Click Events', show: false},
              {name: 'Tango', speciality: 'Conditionals', show: false},
              {name: 'Kami', speciality: 'Webpack', show: false},
              {name: 'Yoshi', speciality: 'Data Diggin', show: false}
            ]
          }
      },
      methods: {
          toggle: function (n) {
            console.log(n);
            if(n===true) n=false;
            else if(n===false) n=true;
            console.log(n);
          }
      }
    }
</script>

<style scoped>

</style>

The problem is that the toggle function isn't working properly because when I click on the button it doesn't the show property of the given object (The first log is false then it changes to true however when I run it again the show property hasn't been changed to true it is false again).

However when I change the code from this:

<button v-on:click="toggle(x.show)">Toggle</button>

To this:

<button v-on:click="toggle(x)">Toggle</button>

And when I change toggle method to this:

toggle: function (n) {
            console.log(n);
            if(n.show===true) n.show=false;
            else if(n.show===false) n.show=true;
            console.log(n);
          }

The program works properly.

Can anyone explain to me why the first time it doesn't work and the second time it works?

Thank you!

David Mathers
  • 163
  • 2
  • 7

1 Answers1

0

I think an approach that probably simplifies what you're going for is something like this:

data() {
  return {
    ninjas: //...,
    activeNinja: 0
  }
},
methods: {
  toggleNinja(index) {
    this.activeNinja = index
  }
}

Now capture your index in your for loop:

<li v-for="(x, index) in ninjas">

And pass the index on button click:

<button v-on:click="toggleNinja(index)">Toggle</button>

And update your show element to observe the activeNinja property:

<h2 v-show="activeNinja === index">{{x.speciality}}</h2>

Now there's no reason to pollute your objects with a show property.

Ohgodwhy
  • 49,779
  • 11
  • 80
  • 110