9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SnowRobinAdvent Calendar 2019

Day 17

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

Last updated at Posted at 2019-12-16

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

やりたいこと

ヘッダーメニュー、フッターメニュー、ハンバーガーメニュー。。。

表示文字・リンク先 は、だいたい一緒なことが多いので、
①一つの配列にまとめちゃって
それぞれのコンポーネントに ②これをimportして 、メニューを生成してみます。
こんな感じ↓
component.png

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

コンポーネント作成

例として、コーポレートサイトによくある こんなハンバーガーメニューを作ってみます。
screencapture-192-168-11-9-3000-2019-12-13-00_50_38.png

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

両方ありますが、
ポイントは、 すべて一つのコンポーネントとして捉える ことです。
左のように、AとB、別々のコンポーネントが混在している、と考えずに
右のように、 違いは第三階層の有無だけ で、全て同じコンポーネントとして考えます。
2種を比べる.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を使って、
配列から要素を順に取り出して リストレンダリングしていきます!

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

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

これで完成です😋

全体のソースはこちら↓

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

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

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?