Vue.js

【Vue.js】コンポーネント間のデータ通信 propsの使い方を解説

5月 11, 2022

Vueのイメージ画像
困っている人
Vue初心者です。コンポーネント間のデータ受け渡しをするためにpropsっていうものがあるらしいけど実際どういうものなの? Vueでpropsを使うにはどうすればいいんだ?

 

こんなお悩みを解決します。

 

Vue.jsのアプリケーション開発を行っていく上では、複数のコンポーネントを利用することになります。

 

表示する要素ごとに部品にして、その部品を組み合わせて画面を構成する形ですね。
RIKU

 

このとき、親コンポーネント→子コンポーネントに対してデータを渡すためにはpropsの知識が不可欠です。

 

なぜなら、コンポーネント内で利用するデータが固定であることはほとんどなく、利用したい場所によって必要なデータは変わってくるからですね。

 

propsを使えないと、データが違うだけで似たようなコンポーネントをいくつも作る必要があり、Vueの良さである再利用性がまったく活かせないことになってしまいます。

 

そうなってしまうと以下のようなデメリットが...

 

propsを使えないと...

  • 1つのファイル内での記述が増えてしまい、保守性が悪くなる
  • 同じコードを何回も書く必要があり効率が悪くなる
  • 開発者以外がコードの意図を汲み取るのが難しくなる

 

逆にpropsを適切に使えるようになれば以下のようなメリットがあります。

 

propsを使うメリット

  • コンポーネントに切り分けて最小単位で開発できるので保守性が高まる
  • データだけ変えればいいため再利用性が高まり、開発効率が上がる
  • 開発範囲が狭く、ファイル名でやっていることが分かるためコードが読みやすくなる

 

コンポーネントには独自の名前を設定することができ、HTML上で呼び出したい箇所にコンポーネント名を記述することで、簡単にコードを呼び出すことができます。

 

また、コンポーネント化することで変更が合った場合にも一つのコンポーネントを修正すればいいだけなので、保守性が高まります。

 

コードの可読性も上がるため、使い回す要素に対してのコンポーネント化は必須です!
RIKU

 

本記事ではpropsの使い方の詳細を説明していきますので、初心者のかたでもpropsの使い方をマスターすることができます。

 

Vueのpropsって何?

冒頭でも触れたように、propsとは親コンポーネントから子コンポーネントへデータを渡すときに使うものです。

 

propsを用いることで親から子への単一方向のデータの流れを実現でき、処理の流れを把握しやすくなります。

 

渡せるデータには以下があります。

 

ポイント

  • 文字列
  • 数値
  • 真偽値
  • 配列
  • オブジェクト

 

propsを使う際は、コンポーネントが正しく処理を行うために、正しいデータを渡す必要があります。

 

Vue.jsでは渡す値のデータタイプやデフォルト値を設定することでバグにつながらないように正しいデータをPropsを利用してコンポーネントに渡す仕組みを備えています。

 

propsの使い方を徹底解説

propsとはどういうものか分かったところで、ここからはpropsを使う方法について解説していきます。

 

コンポーネントの呼び出し

propsの使い方の基本は、①親コンポーネントでプロパティの設定を行い、②子コンポーネントでプロパティの宣言をすることです。

 

上記ではよく分からないと思うため一つずつ説明していきます。

 

まずはpropsを使う前に、親コンポーネントに子コンポーネントから呼び出した要素を表示する方法について見ていきましょう!

 

次に示す書き方がコンポーネント呼び出しの基本的な書式になります。

 

// 親コンポーネント
<template>
  <div class="parent">
    <p>親コンポーネント</p>
    <component-children />
  </div>
 </template>

 <script lang="ts">
 import { defineComponent } from '@nuxtjs/composition-api'
 import ComponentChildren from './ComponentChildren.vue'

 export default defineComponent({
  components: {
    ComponentChildren,
  },

  setup() {
    return {}
  },
})
</script>

 

まず、親コンポーネントでは子コンポーネントを呼び出す必要があり、やっていることは以下になります。

 

  • script内で子コンポーネントを import する
  • 「components」オプションで呼び出す子コンポーネントを指定
  • template内の表示させたい場所に子コンポーネントのタグを埋め込む

 

次に子コンポーネントの中身を見ていくと、ここでは普通に呼び出すテンプレートの中身を記述しておきます。

 

// 子コンポーネント
<template>
  <div class="child">
    <p>子コンポーネント</p>
  </div>
</template>

<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api'

export default defineComponent({
  setup() {
    return {}
  },
})
</script>

 

上記のように書くことで、親子関係にあるコンポーネント間でHTMLが出来上がり、以下のように表示されるようになります。

 

 

これで、コンポーネントの呼び出しについては大丈夫だと思います。

 

続いては本題のpropsの呼び出し方法について見ていきましょう!

 

propsを使ったデータの受け渡し方法を具体例を交えて解説

先程は親子コンポーネントの作成・呼び出しをしましたが、次は具体例を交えながら、データの受け渡し方法を見てみましょう。

 

今回はユーザー情報を親から子へと渡して、子コンポーネント内のtemplate内で受け取ったデータを表示するシンプルな例を解説します。

 

まずは親コンポーネントです。(※先程のコードに必要な記述を追加していきます。)

 

<template>
  <div class="parent">
    <p>親コンポーネント</p>
    <component-children :current-user="currentUser" />
  </div>
</template>

<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api'
import ComponentChildren from '@/components/common/ComponentChildren.vue'

export default defineComponent({
  components: {
    ComponentChildren,
  },

  setup() {
    const currentUser = { name: 'りく', age: 25, gender: '男' }
    return {
      currentUser,
    }
  },
})
</script>

 

親コンポーネント内ではユーザー情報を定義し、<component-children :current-user="currentUser" />の部分で子コンポーネントへデータを渡しています。

 

続いて、子コンポーネントを見ていきます。

<template>
  <div>
    <div class="child">
      <p>子コンポーネント</p>
    </div>
    <div>名前: {{ currentUser.name }}</div>
    <div>年齢: {{ currentUser.age }}</div>
    <div>性別: {{ currentUser.gender }}</div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from '@nuxtjs/composition-api'

export default defineComponent({
  props: {
    currentUser: {
      type: Object,
      default: () => {},
    },
  },

  setup() {
    return {}
  },
})
</script>

 

子コンポーネントにpropsオプションを定義することで、親コンポーネントからprops経由でデータを受け取ることができます。

 

このとき、propsオプションには親コンポーネントで指定した受け渡すデータの変数名を指定します。

 

受け取ったcurrentUserの中身をtemplate内で展開することで、親で定義したユーザー情報を子コンポーネント内で表示することができました!

 

 

 

抑えておきたいポイント

  • 子のscriptタグ内(js記述部分)のpropsで、親から受け取るプロパティ名を列挙
  • 親のtemplateタグ内(html記述部分)で、子の呼び出しとデータの受け渡し

 

propsを利用する際の注意点

 

propsの使い方を見てきましたが、使う際の注意点もいくつかありますので紹介します。

 

Props使用の注意点

  • Propsの命名ルールについて
  • Propsのtypeを正しく設定する
  • 子コンポーネント内で受け取ったデータを更新してはいけない

 

それでは一つずつ見ていきます。

 

Propsの命名ルールについて

 

Props名を設定するときに注意することは、親コンポーネント(HTMLのテンプレート内)での記述と、子コンポーネント(script内での指定)で命名規則が異なることです。

 

上で見てきたように、親コンポーネント内ではcurrent-user のように「ケバブケース」で記述します。

 

逆に子コンポーネント内ではcurrentUserのように「キャメルケース」にする必要があるため注意が必要です。

 

 

 

PropsのTypeを正しく設定する

 

使用した例では簡単なため、オブジェクト型以外を指定することはないかもしれません。

 

しかし、大規模開発などでコードが複雑になると、誤って文字列で渡すべきところを数値で渡したりすることもあります。

 

こういった問題を解決するため、propsにはどのような値が入るかtypeによって予めチェックできます。

 

currentUserにはオブジェクトが入るため、typeにはObjectを設定します。

 

このときObjectの先頭文字は大文字です。小文字にするとエラーになるため注意しましょう!
RIKU

 

その他のtypeは以下のようなものがありますので、型定義を意識して開発していきましょう。

 

typeに指定するもの

  • String(文字列)
  • Array(配列)
  • Number(数値)
  • Boolean(真偽値)

 

子コンポーネント内で受け取ったデータを更新してはいけない

 

これまで見てきたように、Propsは親コンポーネントから子コンポーネントへ一方的にデータを渡すためのものです。

 

なので、子コンポーネント内では受け取ったpropsを更新してはいけません。

 

なぜなら、単一方向へのデータの流れを実現することでコードの保守性を保っているからですね。

 

RIKU
子コンポーネントを色々な箇所で使っている場合、影響範囲が広範囲になり、思ってもいないエラーに繋がるため注意しましょう。

 

逆に子コンポーネントから親コンポーネントへデータを送りたい場合は、emitイベントを利用します。

propsを使って渡された値を更新するときは、emitを使いすべて親のコンポーネントで更新処理を行います。

 

まとめ

今回の記事ではコンポーネント間のデータ受け渡しである、propsについて具体例を交えて解説してきました。

 

コンポーネントにpropsオプションを利用することで、親から子コンポーネントへのデータ受け渡しが可能となり、柔軟な開発ができるようになります。

 

propsを使えるようになることで、保守性が高くなり、開発効率が良くなるんでしたね
RIKU

 

propsを使う際は、コンポーネントが正しく処理を行うために、正しいデータを渡す必要がありました。もう一度確認しておきましょう。

 

渡せるプロパティ一覧

  • String(文字列)
  • Array(配列)
  • Number(数値)
  • Boolean(真偽値)
  • Object(オブジェクト)

 

適切な型を定義してデータを渡すことで、あなたのやりたいこともきっと実現できますよ!

 

注意点でも触れたように命名規則やpropsを定義する際type指定の記述は意識しておきましょう。

 

注意点

  • 親コンポーネント内では「ケバブケース」で記述する
  • 子コンポーネント内では「キャメルケース」で記述する
  • typeを指定する際は先頭文字を大文字にする

 

 

 

最初は使い方に慣れずに戸惑ってしまうかもしれませんが、propsを使いこなして効率の良い開発をできるようになってレベルアップしていきましょう!

-Vue.js

© 2026 株式会社RM Powered by AFFINGER5