Vueのナレッジ
オブジェクトのプロパティを子コンポーネントに渡す
下記のようなオブジェクトのデータを子コンポーネントに渡す時、方法はおおよそ2パターン!
board
のboardTitle
を子コンポーネントで表示させたい
"board": {
"boardTitle": "11/12 TODO",
"todos": []
}
パターン① オブジェクトを省略記法を使って渡す
親コンポーネント
<board-index v-bind="board"/>
子コンポーネント(BoardIndex.vue)
<template>
<div>{{ boardTitle }}</div>
</template>
<script>
export default {
props: {
boardTitle: {
type: String,
required: true
},
todos: {
type: Array
}
}
}
</script>
パターン② オブジェクトをそのまま渡す
親コンポーネント
<board-index :board="board"/>
子コンポーネント(BoardIndex.vue)
<template>
<div>{{ board.boardTitle }}</div>
</template>
<script>
export default {
props: {
board: {
type: Object,
default: () => ({
boardTitle: '',
todos: []
}),
required: true
}
}
}
</script>
別にオブジェクトのプロパティを個々にバインドさせる方法もあります。
場面によって使い分けることができそうです。
話が少し逸れますが、パターン②でboard
のdefault
を関数で返しています。
これは、
propsのデフォルト値に指定したオブジェクトや配列は、参照が共有される
ことを防ぐためです。
参照が共有されてしまうと、複数のvueインスタンスが同一のオブジェクトを参照し、同一のオブジェクトに変更を加えてしまう状況が発生します。
子コンポーネントに渡したデータの変更を親コンポーネントに反映する
親から子へpropsでデータを渡したとき、
子側でそのpropsデータを直接変えようとするとvueに怒られてしまいます。
では、どうすればいいか、備忘録でまとめておきます。
親コンポーネント
<child-component v-model="parentData"/>
子コンポーネント(ChildComponent.vue)
<script>
export default {
props: {
parentData: {
type: String,
default: ''
}
},
computed: {
inputData: {
get() {
return this.parentData
},
set(newVal) {
this.$emit('input', newVal)
}
}
}
}
</script>
親から受け取ったprops
をcomputed
を通して別名のプロパティinputData
として受け取り、子側でinputData
に変更があった場合、set
関数で新しい値を取得して親に返します。
$emit
でinput
イベントを送ることで親のv-model
の値にデータがバインドされます。
これができるのは、v-model
(= v-on:input
とv-bind:value
)で双方向データバインディングを行っているためですね。