Deji James
Deji James

Reputation: 437

Vue3 toggle element in v-for loop

I am looping through an array on v-for loop in vue 3. Is there a way to toggle the v-show of a paragraph by clicking on the Heading element. Below is my code :

<div class="defs">
<ul v-for="(d, index) in definitions"
              :key="'d' + index">
   <li>
  <div class="project" >
    <div @click="showDetails" class="actions">
      <h3>{{ d.title }}</h3>
      <div class="icons">
         <span  class="material-icons" ><i class="fas fa-trash-alt"></i></span> 
  <span class="material-icons" ><i class="fas fa-pencil-alt"></i></span> 
      </div>
    </div>
    <div v-if="show" class="details">
      <p>{{d.explanation}}</p>
    </div>
  </div>
  </li>
</ul>
</div>



<script>
import { ref } from "vue";
import { projectDatabase} from '../../firebase/config'

export default {
  props: ['id'],
  setup(props){

  const show = ref(false);

  
  
  const showDetails = () =>{
    show.value = !show.value
  }

      return {
      definitions, props, show, showDetails, 
    }
  }
}
</script>

I know we cant use this in composition API. so how can we solve the toggle issue ?

Upvotes: 2

Views: 1835

Answers (1)

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23510

Try like following snippet, here is the codesandbox with composition API

const demo = {
  data() {
    return {
      definitions: [
        { title: "aaa", explanation: "aaa" },
        { title: "bbb", explanation: "bbb" },
        { title: "ccc", explanation: "ccc" },
      ],
      show: null
    }
  },
  methods: {
    showDetails(idx) {
      this.show === idx ? (this.show = null) : (this.show = idx);
    }
  },
  // same code with coposition API
  /*import { ref } from "vue";
  import { projectDatabase} from '../../firebase/config'
  setup() {
    const show = ref(null);
    const definitions = ref([
      { title: "aaa", explanation: "aaa" },
      { title: "bbb", explanation: "bbb" },
      { title: "ccc", explanation: "ccc" },
    ]);

    const showDetails = (idx) => {
      show.value === idx ? (show.value = null) : (show.value = idx);
    };

    return { definitions, show, showDetails }
  },*/
};
Vue.createApp(demo).mount("#demo");
<script src="https://unpkg.com/vue@next"></script>
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous" />
<div id="demo">
  <div class="defs">
    <ul>
      <li v-for="(d, index) in definitions" :key="index">
        <div class="project">
          <div @click="showDetails(index)" class="actions">
            <h3>{{ d.title }}</h3>
            <div class="icons">
              <span class="material-icons"
                ><i class="fas fa-trash-alt"></i
              ></span>
              <span class="material-icons"
                ><i class="fas fa-pencil-alt"></i
              ></span>
            </div>
          </div>
          <div v-if="show === index" class="details">
            <p>{{ d.explanation }}</p>
          </div>
        </div>
      </li>
    </ul>
  </div>
</div>

Upvotes: 1

Related Questions