admin管理员组

文章数量:1417107

I am building a simple vue accordion, when I click one accordion they all open and that is not the behavior I am after. Is there a way to only open the one clicked? I assumed "this" would take care of that but I am no having luck.

html:

<div id="accordion" class="accordion-container">
            <div class="accordion" :class="accordionClasses">
              <div class="accordion-header" @click="toggleAccordion">
                Accordion 1
                <i class="fal fa-plus" />
                <!--  <i class="fal fa-minus" /> -->
              </div>
              <div class="accordion-body">
                <div class="accordion-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. <strong>Pellentesque risus mi</strong></div>
              </div>
            </div>
            <div class="accordion" :class="accordionClasses">
              <div class="accordion-header" @click="toggleAccordion">
                Accordion 2
                <i class="fal fa-plus" />
                <!--   <i class="fal fa-minus" /> -->
              </div>
              <div class="accordion-body">
                <div class="accordion-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. <strong>Pellentesque risus mi</strong></div>
              </div>
            </div>
            <div class="accordion" :class="accordionClasses">
              <div class="accordion-header" @click="toggleAccordion">
                Accordion 3
                <i class="fal fa-plus" />
                <!-- <i class="fal fa-minus" />-->
              </div>
              <div class="accordion-body">
                <div class="accordion-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. <strong>Pellentesque risus mi</strong></div>
              </div>
            </div>
          </div>

js:

export default {
  name: 'trial-page',
  data() {
  return {
  isOpen: false
};
  },
  puted: {
accordionClasses: function() {
  return {
    'is-closed': !this.isOpen
  };
 }
},
   methods: {
toggleAccordion: function() {
  this.isOpen = !this.isOpen;
 }
}
};

I am building a simple vue accordion, when I click one accordion they all open and that is not the behavior I am after. Is there a way to only open the one clicked? I assumed "this" would take care of that but I am no having luck.

html:

<div id="accordion" class="accordion-container">
            <div class="accordion" :class="accordionClasses">
              <div class="accordion-header" @click="toggleAccordion">
                Accordion 1
                <i class="fal fa-plus" />
                <!--  <i class="fal fa-minus" /> -->
              </div>
              <div class="accordion-body">
                <div class="accordion-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. <strong>Pellentesque risus mi</strong></div>
              </div>
            </div>
            <div class="accordion" :class="accordionClasses">
              <div class="accordion-header" @click="toggleAccordion">
                Accordion 2
                <i class="fal fa-plus" />
                <!--   <i class="fal fa-minus" /> -->
              </div>
              <div class="accordion-body">
                <div class="accordion-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. <strong>Pellentesque risus mi</strong></div>
              </div>
            </div>
            <div class="accordion" :class="accordionClasses">
              <div class="accordion-header" @click="toggleAccordion">
                Accordion 3
                <i class="fal fa-plus" />
                <!-- <i class="fal fa-minus" />-->
              </div>
              <div class="accordion-body">
                <div class="accordion-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. <strong>Pellentesque risus mi</strong></div>
              </div>
            </div>
          </div>

js:

export default {
  name: 'trial-page',
  data() {
  return {
  isOpen: false
};
  },
  puted: {
accordionClasses: function() {
  return {
    'is-closed': !this.isOpen
  };
 }
},
   methods: {
toggleAccordion: function() {
  this.isOpen = !this.isOpen;
 }
}
};
Share Improve this question asked Jan 15, 2020 at 14:11 hendy0817hendy0817 1,0792 gold badges28 silver badges61 bronze badges 2
  • Do you want only one open at a time, or do you want to be able to have multiple open at once? (if multiple are clicked) – T. Short Commented Jan 15, 2020 at 14:18
  • yes multiple open at once. There is going to be an "open all" "close all" eventually but for now just want one open at a time with the ability to open all. – hendy0817 Commented Jan 15, 2020 at 14:21
Add a ment  | 

2 Answers 2

Reset to default 7

If you want to keep track of which accordion section is open or closed, you need t give each one an index and use that as a tracking tool. As you are creating a list I strongly remend you use v-for.

Overall your code could do with some refactoring so I rewrote it a bit to give you an example of what you should be aiming for:

<template>
  <div id="accordion" class="accordion-container">
    <div
      v-for="(item, index) in items"
      :key="index"
      :class="[
        'accordion',
        { 'is-open': isOpen.includes(index) }
      ]"
    >
      <div class="accordion-header" @click="toggleAccordion(index)">
        {{ item.title }}
        <i v-if="!isOpen.includes(index)" class="fal fa-plus"/>
        <i v-else class="fal fa-minus"/>
      </div>
      <div class="accordion-body">
        <div class="accordion-content">
          {{ item.text }}
          <strong>{{ item.sub }}</strong>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "trial-page",
  data() {
    return {
      items: [
        {
          title: "Accordion 1",
          text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          sub: "Pellentesque risus mi"
        },
        {
          title: "Accordion 2",
          text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          sub: "Pellentesque risus mi"
        },
        {
          title: "Accordion 3",
          text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
          sub: "Pellentesque risus mi"
        }
      ],
      isOpen: []
    };
  },
  methods: {
    toggleAccordion(index) {
      if (this.isOpen.includes(index)) {
        this.isOpen = this.isOpen.filter(i => i !== index);
        return;
      }

      this.isOpen.push(index);
    }
  }
};
</script>

<style>
.accordion:not(.is-open) .accordion-body {
  display: none;
}
</style>

Here is a codepen to test it out: https://codesandbox.io/s/blazing-water-icpxw

You may need to adjust somethings to suit your needs.

You can have a look at .bind() method:

Bind creates a new function that will have this set to the first parameter passed to bind().

本文标签: javascripttoggle only accordion clicked vuejsStack Overflow