n番煎じですが試行錯誤した結果を残しておきます。
いろんなやり方があると思いますが、個人的に一番しっくり来たやり方です。
結論
<template>
  <div class="a-accordion">
    <button @click="opened = !opened">
      Click
    </button>
    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @before-leave="beforeLeave"
      @leave="leave"
    >
      <div v-if="opened" class="a-accordion-inner">
        Accordion
      </div>
    </transition>
  </div>
</template>
<script>
export default {
  data() {
    return {
      opened: false
    }
  },
  methods: {
    beforeEnter(el) {
      el.style.height = '0'
    },
    enter(el) {
      el.style.height = el.scrollHeight + 'px'
    },
    beforeLeave(el) {
      el.style.height = el.scrollHeight + 'px'
    },
    leave(el) {
      el.style.height = '0'
    }
  }
}
</script>
<style scoped lang="scss">
.a-accordion {
  .a-accordion-inner {
    overflow: hidden; // 閉じるときに他要素に被らないように必須。
    transition: height 0.2s ease-in-out; // 高さの変更に対して連続的に変化させる。
  }
}
</style>
ポイントは
- 開閉する要素に overflow,transitionを指定する。
- 
transionのフックでheightを変更する。
の2つです!
参考
https://jp.vuejs.org/v2/guide/transitions.html
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
http://lab.astamuse.co.jp/entry/2018/10/15/154737
https://qiita.com/mimoe/items/7ad8d9ea9fc4299da6bc
