Vueでアコーディオンメニューを実装する方法をいくつか試してみた
Vueでアコーディオンメニューを実装するにあたっていくつかの方法を試したのでまとめておきます。
温かい目でご覧ください。
checkboxとCSS
Vueを使った実装ではありませんが、フレームワークに依存する実装ではないので一応試しました。
checkboxの状態が開閉のフラグとなってます。
隣接セレクタとtransitionプロパティによってアニメーションを行います。
code: HTML
<input id="flag" class="check" type="checkbox" />
<label class="title" for="flag">title</label>
<div class="content">
<p>content</p>
</div>
code: CSS
.check {
display: none;
}
.content {
height: 0;
transition: .3s;
overflow: hidden;
}
.check:checked + .title + .content {
height: 30px;
}
v-showとtransitionとCSS
v-showを使用して開閉を制御するためフラグとなる変数を定義します。
transitionコンポーネントにより追加されたクラスにアニメーションを設定します。
code: HTML
<div id="app">
<div @click="onClickTitle()">title</div>
<transition name="accordion">
<div class="content" v-show="active">
<p>content</p>
</div>
</transition>
</div>
code: CSS
.content {
height: 40px;
overflow: hidden;
}
.accordion-enter-active,
.accordion-leave-active {
transition: height .3s;
}
.accordion-enter,
.accordion-leave-to {
height: 0;
}
code: JavaScript
new Vue({
el: '#app',
data: () => ({
active: false,
}),
methods: {
onClickTitle() {
this.active = !this.active;
},
},
});
onuma.icon え、これで動くの!?Codepenとかで書いていたら共有して欲しいです!😄あ、heightは固定なのか・・・。
Sekita.icon heightが固定だからこの量です、、笑
vue-slide-up-down
jQueryのslideUP/SlideDownのようなことができるライブラリです(jQueryあんまり知らないのでピンときてないです)。
propsのactiveによって開閉を制御するためフラグとなる変数を定義します。
code: HTML
<div id="app">
<div @click="onClickTitle()">title</div>
<vue-slide-up-down :active="active">
<div>content</div>
</vue-slide-up-down>
</div>
code: JavaScript
Vue.component('vue-slide-up-down', VueSlideUpDown);
new Vue({
el: '#app',
data: () => ({
active: false,
}),
methods: {
onClickTitle() {
this.active = !this.active;
},
},
});
vue-bulma-accordion
CSSフレームワークのBULMAがベースとなっているライブラリです。
デフォルトのスタイルがあります。
メニューのタイトルと内容をslot属性によって指定します。
code: HTML
<div id="app">
<bulma-accordion dropdown=true>
<bulma-accordion-item>
<h4 slot="title">title</h4>
<p slot="content">content</p>
</bulma-accordion-item>
</bulma-accordion>
</div>
code: JavaScript
const BulmaAccordion = window.BulmaAccordion.BulmaAccordion;
const BulmaAccordionItem = window.BulmaAccordion.BulmaAccordionItem;
new Vue({
el: '#app',
components: {
BulmaAccordion,
BulmaAccordionItem
},
});
CSSフレームワークのBULMAがベースとなっているライブラリ
onuma.icon これってBULMAのCSSが入っていないといけない感じですかね?🤔
Sekita.icon BULMAも必要です!
Vuetify
VueのUIフレームワークです。
code: HTML
<div id="app">
<v-row>
<v-expansion-panels accordion=true multiple=true>
<v-expansion-panel>
<v-expansion-panel-header>title</v-expansion-panel-header>
<v-expansion-panel-content>content</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</v-row>
</div>
code: JavaScript
new Vue({
el: '#app',
vuetify: new Vuetify(),
});
各実装方法の感想
checkboxとCSS
checkboxで開閉を制御できるので、アコーディオンメニューのためだけの変数やメソッドをわざわざ定義する必要がない点が良いと思いました。
v-showとtransitionとCSS
checkboxを使用した実装と記述量はあまり変わらないですが、htmlの可読性はこっちの方が高そうだなと思いました。
vue-slide-up-down
heightを設定しなくてもアニメーションできる上にライブラリでデフォルトのスタイルがないので汎用性が高いと思いました。
vue-bulma-accordion
記述量が少ない上にslot属性でメニューのタイトルや内容を指定できるので使いやすいと思いました。
ただ、Githubのスター数が少ないので採用される機会は少なそうです。
Vuetify
vue-bulma-accordionと同様に記述量が少なくて良いと思いました。
まとめ
記述量が最も少なく済むのはvue-bulma-accordionやVuetifyですが、これらは自由にデザインを決めたい場合に不便なため、今のところvue-slide-up-downによる実装が一番良いという結論に至りました。
onuma.icon 色々調べてくれてありがとうございます!結構まとまっていていいと思いました!👍
👍 onuma onuma.icon がいいねしました on 2020/5/11