はじめに
Vue.jsを使ってWEBアプリを構築する際、コンポーネント化を行い、部品の再利用性を高めると思います。
その際、親コンポーネント⇔子コンポーネント⇔孫コンポーネントでの値の受け渡し(双方向データバインディング)について、
検討してみたので、備忘録を残します。
やりたい事
親コンポーネントで保持しているデータを子コンポーネントに渡し、
子コンポーネントでは孫コンポーネントに受け取った値を渡して、
孫コンポーネントではドロップダウンの初期選択を行う。
孫コンポーネントのドロップダウンで選択を変更した場合、子コンポーネントそして親コンポーネントへと値を戻す。
図にすると以下のような感じ。
やってみた
▼親コンポーネント(Sample0.vue)
<template> <div> <sample1 v-model="selectedId"></sample1> selectedId: {{ selectedId }} </div> </template> <script lang="ts"> import Vue from 'vue'; import Sample1 from "./Sample1.vue"; export default Vue.extend({ name: "Sample0", components: { Sample1 }, data(){ return { selectedId: 5 } }, methods: { checkData: function(){ alert(this.selectedId); } } }) </script>
親コンポーネントのポイント
▼子コンポーネント(Sample1.vue)
<template> <div> <label>テスト</label> <sample2 v-model="selectedId" @input="$emit('input', $data.selectedId);"></sample2> </div> </template> <script lang="ts"> import Vue from 'vue'; import Sample2 from "./Sample2.vue"; export default Vue.extend({ name: "Sample1", components: { Sample2 }, props: ['value'], data() { return { selectedId : this.value } } }) </script>
子コンポーネントのポイント
- 親コンポーネントで渡された値は、propsのvalueで受け取る。
- propsは、読み取り専用項目なので、propsのvalueで受け取った値は初期値として使い、 dataプロパティのselectedId に代入しておく
- selectedIdは、v-modelで双方向データバインディングさせる
- 親コンポーネントの値を更新するため、v-on.input(@input)で、$emitでイベントを通知する。
▼孫コンポーネント(Samle2.vue)
<template> <div> <sui-dropdown selection :options="options" v-model="selectedValue" @input="$emit('input', $data.selectedValue);" /> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ name : "Sample2", props: ['value'], data(){ return { selectedValue: this.value, options: [ { text: 'text1', value: 1 }, { text: 'text2', value: 2 }, { text: 'text3', value: 3 }, { text: 'text4', value: 4 }, { text: 'text5', value: 5 }, { text: 'text6', value: 6 }, { text: 'text7', value: 7 }, { text: 'text8', value: 8 }, { text: 'text9', value: 9 } ] } }, methods: { emitInput: function(): void{ this.$emit('input', this.selectedValue); } } }) </script>
孫コンポーネントのポイント
実行してみた
初期値の5が選択されている
↓
孫コンポーネントのドロップダウンを変更すると、親コンポネントの値も変わっている
メモ
上記の例では、valueをpropsで受けていますが、
コンポーネントの要件によっては、value以外で受け取りたいケースがあると思います。
そのときは、modelプロパティを使うことで対応するのかなと思います。
↓参考
jp.vuejs.org
最後に・・・
もっと簡潔に書ける方法があれば、コメントください!