Vue

by Shatge

HTML

<div id="app">
   <div class="ui-accordeon">
      <div class="ui-accordeon__heading"
        @click="visible = !visible">
        <div class="ui-accordeon__title">Title</div>
      </div>

      <transition name="slide"
        @after-enter="afterEnter"
        @enter="enter"
        @before-leave="beforeLeave">
        <div v-show="visible" 
          class="slide-animation">
          <div class="ui-accordeon__content">Content</div>
        </div>
      </transition>
    </div>
</div>

CSS

body {
  padding: 20px;
}

.ui-accordeon {
  background-color: #eee;
}

.ui-accordeon__heading {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    padding: 10px 20px;
    border-bottom: 1px solid #a86832;
    cursor: pointer;
    user-select: none;
 }
  
 .ui-accordeon__title {
    font-size: 15px;
    font-weight: 700;
  }
  
  .ui-accordeon__content {
    padding: 24px 20px;
    min-height: 4px;
  }
  
  .slide-animation {
    transition: all 0.5s ease;
    overflow: hidden;
  }

Vue

new Vue({
  el: "#app",
  
  data() {
    return {
      visible: false,
    }
  },
  
  methods: {
  	enter(el) {
      el.style.height = "auto";
      const endWidth = getComputedStyle(el).height;
      el.style.height = "1px";
      el.offsetHeight;
      el.style.height = endWidth;
    },

    afterEnter(el) {
      el.style.height = "auto";
    },

    beforeLeave(el) {
      el.style.height = getComputedStyle(el).height;
      el.offsetHeight;
      el.style.height = "1px";
    },
  }
})