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