【実装編】Vue.jsで再利用可能なコンポーネントを実装する方法


[props編](https://qiita.com/h-iwamori/private/9b36d684c74e0b3e347a)
slot編
実装編👈今ここ

## はじめに
どうすれば再利用可能なコンポーネントを実装することができるのか？
「props」と「slot」を使って実装してみます。

バージョン
Vue.js 2.6.11

## 実装

アコーディオンを用意しました。
必要に応じてタイトル右横に「update」「new」バッジが付与できます。

- `App.vue`で`Accordion.vue`をimport
- `Accordionタグ`の中に`名前付きslot`を使用してコンテンツをコンポーネントに追加する
- `props`type, required, default, validatorをそれぞれ指定

**propsの種類としては**
typeA -> 何もなし
typeB -> update
typeC -> new

```App.vue
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png" width="25%" />

    <div>
      <p>アコーディオン</p>
      <Accordion variant="typeA">
        <template v-slot:title>1.コンテンツについて</template>
        <template v-slot:content>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Sunt quaerat
          consequatur ipsum quia a quod sed cum quae maxime reprehenderit, porro
          sequi exercitationem voluptate saepe minus in ullam. Beatae, itaque!
        </template>
      </Accordion>

      <Accordion variant="typeB">
        <template v-slot:title>2.不具合について</template>
        <template v-slot:content>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Sunt quaerat
          consequatur ipsum quia a quod sed cum quae maxime reprehenderit, porro
          sequi exercitationem voluptate saepe minus in ullam. Beatae, itaque!
          <br />
          <br />
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Sunt quaerat
          consequatur ipsum quia a quod sed cum quae maxime reprehenderit, porro
          sequi exercitationem voluptate saepe minus in ullam. Beatae, itaque!
        </template>
      </Accordion>

      <Accordion variant="typeC">
        <template v-slot:title>3.新コンテンツのお知らせ</template>
        <template v-slot:content>
          Lorem ipsum, dolor sit amet consectetur adipisicing elit. Facilis
          magnam ullam repudiandae, dolorem dignissimos debitis at possimus!
          Reprehenderit enim illum asperiores, nihil labore veniam vitae,
          aperiam id a rem consequatur.
          <a href="#">more</a>
        </template>
      </Accordion>

      <Accordion>
        <template v-slot:title> 4.その他</template>
        <template v-slot:content> 準備中... </template>
      </Accordion>
    </div>
  </div>
</template>

<script>
import Accordion from "./components/Accordion";

export default {
  name: "App",

  components: {
    Accordion,
  },
};
</script>
```

```components/Accordion.vue
<template>
  <div
    class="accordion"
    :class="[
      { 'accordion--A': variant === 'typeA' },
      { 'accordion--B': variant === 'typeB' },
      { 'accordion--C': variant === 'typeC' },
    ]"
  >
    <button
      class="accordion__button"
      @click="toggleAccordion()"
      :class="{ 'is-active': isOpen }"
    >
      <slot name="title" />
    </button>

    <div class="accordion__content" v-show="isOpen">
      <slot name="content" />
    </div>
  </div>
</template>

<script>
export default {
  name: "",

  props: {
    variant: {
      type: String,
      required: false,
      default: "typeA",
      validator: (value) => ["typeA", "typeB", "typeC"].includes(value),
    },
  },

  data() {
    return {
      isOpen: false,
    };
  },

  methods: {
    toggleAccordion() {
      this.isOpen = !this.isOpen;
    },
  },
};
</script>
```

https://codesandbox.io/s/accordioncomponent-ke9mf

## 最後に
参考にどうぞ！