Vue.js v2のprops | 親から子への値の受け渡し方法
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>