作成日: 2023/10/27
0

Vue3でAccordionを実装しよう

今回はよく使われるアコーディオン
jsだと

<div class="accordion" id="js-accordion">
	<h1>格要素にアクセスする</h1>

	<a href="" class="accordion-trigger">Q1. .targetと.currentTargetの違いは?</a>
	<p>A1. .targetは、クリックされた要素内にあるタグまで取得。<br>.currentTargetはクリックされた要素以外は取得しない。<br>厳密にするかどうかの違い。</p>
	<a href="" class="accordion-trigger">Q1. .nextElementSiblingとは?</a>
	<p>.nextElementSiblingは、指定されたDOM要素の次にあるDOMを取得する。</p>
</div>
<script>
// class化
class Accordion {
	//初期化
	constructor(obj) {
		const $target = document.querySelector(obj.foocName);
		const $accordions = $target.getElementsByTagName(obj.tagName);
        
		const triggerLen = $accordions.length;
		for( let i = 0; i < triggerLen; i++) {
			$accordions[i].addEventListener('click', (e) => this.clickHand(e));
		}
	}

	//関数
	clickHand(e) {
		e.preventDefault();
            
		const $target = e.currentTarget;
		const $content = $target.nextElementSibling;
		if($content.classList.contains('active') === false) {
			$content.classList.add('active')
		} else {
			$content.classList.remove('active')
		}
	}
}

//開閉するDOM要素
	const faqAccodion = new Accordion({
		foocName: '#js-accordion',
		tagName: 'a'
	})
</script>
<style>
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

h1 {
    margin: 20px 0;
    text-align: center;
}

.accordion-trigger {
    padding: 10px 0;
    background-color: aqua;
    display: block;
    color: rgb(81, 81, 81);
    padding-left: 10px;
    border: 1px solid rgb(38, 38, 38);
}

p {
    border: 1px solid rgb(38, 38, 38);
    padding: 20px;
    display: none;
}

.active {
    display: block;
    animation: fade .5s ease;
}

@keyframes fade {
    0%{
      opacity: 0;
    }
    100%{
      opacity: 1;
    }
}
</style>

jQuery

参考サイト

<div class="accordion">
    <h2 class="accordion__title">これクリックしたら開閉するよ!</h2>
    <div class="accordion__content">
        <p class="accordion__text">この中にアコーディオンのコンテンツを入れていきます。</p>
        <p class="accordion__text">この中にアコーディオンのコンテンツを入れていきます。</p>
        <p class="accordion__text">この中にアコーディオンのコンテンツを入れていきます。</p>
    </div>
</div>
<script>
$(function () {
    $('.accordion__title').on('click', function () {
        $(this).next().slideToggle();
    });
});
</script>

Vue3での実装

結構簡単

<template>
  <section>
    <dl>
      <dt :class="{open}" @click="toggle">Q.{{ question }}</dt>
      <dt v-show="open">A.{{answer}}</dt>
    </dl>
  </section>
</template>
<script setup lang="ts">
import { ref } from "vue";

const open = ref(false);

interface Props {
  question:String,
  answer:String,
}

defineProps<Props>()

const toggle = function(){
  open.value = !open.value
}
</script>

あとは親コンポーネントでprops要素をタグ内に書けばOK


フロントエンドエンジニアを頑張って勉強中。 最近はVueやNuxtを勉強中です。 コミュニティなどあれば参加してみたいと思ってます。 どうぞ、生暖かい目で見ていただけると幸いです。