【Vue.js】異なるコンポーネントに、同じデータを渡して一括管理する

こんにちは。
最近、nuxtでの開発にハマっているマークアップエンジニアのkiyoseです。
独学でvue.jsを一ヶ月ほどみっちり勉強したのち、業務でnuxtを使い初めて4ヶ月目になります。
今回は、別々のコンポーネントを作成し、そこに同じ配列を渡してデータを一括管理してみます。

# やりたいこと
ヘッダーメニュー、フッターメニュー、ハンバーガーメニュー。。。

表示文字・リンク先 は、だいたい一緒なことが多いので、
 **①一つの配列にまとめちゃって** 、
それぞれのコンポーネントに **②これをimportして** 、メニューを生成してみます。
こんな感じ↓
![component.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/fe3efabe-345a-8a86-1e80-dbb1f202ffbe.png)



こうすることで、メニューのリンク先変更やテキスト修正が入っても、一箇所修正するだけでOKなので、
変更忘れを防ぐことができますね♪


# コンポーネント作成
例として、コーポレートサイトによくある こんなハンバーガーメニューを作ってみます。
![screencapture-192-168-11-9-3000-2019-12-13-00_50_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/8dbfd8b5-9ed2-caaa-f474-7536df0675db.png)

↑第二階層と、*第三階層がある* 第二階層。

両方ありますが、
ポイントは、 **すべて一つのコンポーネントとして捉える** ことです。
左のように、AとB、別々のコンポーネントが混在している、と考えずに
右のように、 **違いは第三階層の有無だけ** で、全て同じコンポーネントとして考えます。
![2種を比べる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/4e7435db-4597-1ba3-878c-fd96d25dec33.png)


では、ソースを見ていきましょう。

### 1、まずメニューデータ配列.jsをインポートします。

```HamburgerMenu.vue
<script>
 import menuDataArray from '~/data/menuData.js'
</script>
```
### 2、データオブジェクトで、 importした配列を値に設定します。

```HamburgerMenu.vue
<script>
export default {
 data() {
     return {
       menuData: menuDataArray
     }
  }
}
</script>
```

※データオブジェクトとして定義するプロパティは、
 **関数の戻り値でオブジェクトとして出す必要がある** ので、記法に注意です。

```
data: {   
   menuData: menuDataArray
 }
```
としちゃうとエラーになっちゃいますよ。

### 3、いよいよv-forを使って、<br>配列から要素を順に取り出して リストレンダリングしていきます！

まず、第二回層からいきます。

```HamburgerMenu.vue
<template>
  <!-- 第二階層リスト -->
  <ul>
    <li v-for="(menuDataItem, index) in menuData" :key="index">
      <nuxt-link :to="menuDataItem.link">
        {{ menuDataItem.text }}
      </nuxt-link>
    </li>
  </ul>
</template>
```
ぐるぐる回して、menuData.js内のlinkとtextを出力します。

### 4、第三階層を作っていきましょう。
先述したとおり、**第三階層の有無**  の違いがあるだけで、すべて同じコンポーネントです。
第三階層用のデータ(hierarchy3配列)が あったら表示、なかったら非表示するように作っていきます。
あったら表示、なかったら非表示。。。
そうです！！！ DOMを生成したり削除してくれる、**v-if** の登場です！

```HamburgerMenu.vue
<template>
  <!-- 第二階層リスト -->
  <ul>
    <li v-for="(menuDataItem, index) in menuData" :key="index">
      <nuxt-link :to="menuDataItem.link">
        {{ menuDataItem.text }}
      </nuxt-link>

      <!-- 第三階層リスト↓↓ -->
      <ul v-if="menuDataItem.hierarchy3">
        <li v-for="(hierarchy3Item, index2) in menuDataItem.hierarchy3" :key="index2">
          <nuxt-link :to="hierarchy3Item.link">
            {{ hierarchy3Item.text }}
          </nuxt-link>
        </li>
      </ul>
      <!-- 第三階層リスト↑↑ -->
      
    </li>
  </ul>
</template>
```

↑第二階層リストの中に、第三階層リストを差し込みました。
manuData.jsの中に、hierarchy3配列があれば第三階層を生成するようにします。

```
<!-- 第三階層リスト↓↓ -->
<ul v-if="menuDataItem.hierarchy3">
```


![第三階層.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/6c76ae18-7b96-515a-0cce-0398e9186c66.png)



これで完成です😋

全体のソースはこちら↓



```HamburgerMenu.vue
<template>
  <!-- 第二階層リスト -->
  <ul>
    <li v-for="(menuDataItem, index) in menuData" :key="index">
      <nuxt-link :to="menuDataItem.link">
        {{ menuDataItem.text }}
      </nuxt-link>

      <!-- 第三階層リスト↓↓ -->
      <ul v-if="menuDataItem.hierarchy3">
        <li v-for="(hierarchy3Item, index2) in menuDataItem.hierarchy3" :key="index2">
          <nuxt-link :to="hierarchy3Item.link">
            {{ hierarchy3Item.text }}
          </nuxt-link>
        </li>
      </ul>
      <!-- 第三階層リスト↑↑ -->
      
    </li>
  </ul>
</template>

<script>
import menuDataArray from '~/data/menuData.js'

export default {
  name: 'HamburgerMenu',
  data() {
    return {
      menuData: menuDataArray
    }
  }
}
</script>

```

ヘッダー・フッターなどでも、
同じようにデータを受け取り、`<li>` を回すようにコンポーネントを作っておけば、
一箇所の変更だけで済み、又、
第二階層、第三階層が増えたときも、配列にちょちょっと書き足すだけなので簡単です。


![フッター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527850/815a6aae-bae1-dcdb-5c03-baa83526491a.png)


vue好き！もっと勉強しよう😀