Vue.js v2のprops | 親から子への値の受け渡し方法

Vue.js

Vue.jsのpropsの使い方です。
簡単な例から見てみましょう。

props

todoアプリの場合をみてみます。
App.vueとTask.vue、TaskItem.vueという2つのコンポーネントがあるとします。
親のApp.vueの中にTask.vueをいれて、Task.vueの中にtodoのアイテムリストのみを扱うTaskItem.vueをいれるとします。

App.vueからTask.vueにデータを渡す

App.vueにデータがある場合、Task.vueにそのデータを渡すときに、propsを使います。
App.vue template

  <div id="app">
    <task :tasks="tasks"></task>
  </div>

このように、App.vueのデータのtasksをtasksという名前でTask.vueに渡します。
templateタグ内でTask.vueを使うためには、importしてcomponentsとして追加する必要があります。

App.vue script

import Task from "./components/Task";

export default {
  name: "App",
  components: {
    Task,
  },
  data() {
    return {
      tasks: [
        {
          id: 1,
          title: "Vueを勉強する",
          completed: false,
        },
...
      ],
    };
  },
};

上のようにすることで、importして、componentsという追加することができます。

そして、Task.vueでそのデータを受け取る処理を書きます。

Task.vue script

  props: ['tasks'],

そして、Task.vueのtemplateタグ内でそのデータを使います。

Task.vue template

<TaskItem
  v-for="(task, index) in tasks" :key="task.id"
  :task="task"
/>

このようにしてv-forで一つひとつのデータを取り出すなどの処理ができるようになります。

別の例

親コンポーネントApp.vue

通常string型のデータを直接渡すことは少ないため、v-bindを使ってdata()に変数を作成します。(親)
templateタグ内で使います。(親)
propsを配列でデータを格納します。(子)
templateタグ内で使います。(子)

<template>
<!-- App.vue root component -->
  <h1>{{ title }}</h1>
  <!-- 
    親であるApp.vueからModal.vueにstring型データを直接渡したいとき。
    1.App.vueでheaderを使う
    2.Modal.vueでprops:['header'],を設定  
    3.Modal.vueで<h1>{{ header }}</h1>のようにして使う
    <Modal header="ヘッダー部分" text="ここにテキスト"/> -->
    
    <!-- string型以外のときはv-bindを使う。 -->
  <Modal :header="header" :text="text" theme="sale" />
  <hr>
  <input type="text" ref="name">
  <button @click="handleClick">click me</button>
</template>
<script>
import Modal from './components/Modal'

export default {
  name: 'App',
  components: { Modal },
  data() {
    return {
      title: 'My First Vue App',
      header: 'ヘッダー部分',
      text: 'ここにテキスト',
    };
  },
 }
};
</script>
<style scoped>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
h1 {
  border-bottom: 1px solid #2c3e50;
  display: inline-block;
  padding-bottom: 10px;
}
</style>

子コンポーネントModal.vue

<template>
  <div class="backdrop">
    <!-- 動的にしたい場合はclassもv-bindを使う -->
    <!-- 静的でいい場合は通常通り -->
    <!-- :class="{ sale: theme === 'sale'}"
    themeをv-bindしたclass内で使うことで特定の条件下でclassを付与したりすることができる
     -->
    <div class="modal" :class="{ sale: theme === 'sale'}">
      <h1>{{ header }}</h1>
      <p>{{ text }}</p>
    </div>
  </div>
</template>
<script>
export default {
  // 親から値を受け取るprops
  props:['header', 'text', 'theme'],
}
</script>
<style scoped>
  .modal {
    width: 400px;
    padding: 20px;
    margin: 100px auto;
    background-color: white;
    border-radius: 10px;
  }
  .backdrop {
    top: 0;
    position: fixed;
    background-color: rgba(0,0,0,0.5);
    width: 100%;
    height: 100%;
  }
  h1 {
    color: #02cfb4;
    border:none;
    padding: 0;
  }
  .modal.sale {
    background-color: crimson;
    color: white;
  }
  .modal.sale h1 {
    color: white;
  }
</style>

Vue.js

Posted by devsakaso