Vueで親から子テンプレートに受け渡したデータ(変数)をsetterで操作する方法について。
Vueの単一テンプレ内でsetterを使う場合はcomputedを使ったが、親から子にデータを受けわたす場合はwatchプロパティを使う。
computedを使ったgetterとsetterについてはこちら
考え方
単一テンプレートの場合はcomputedにgetterとsetterを記述すればいいが、子へ受け渡した場合、その変数はpropsで宣言されるため、computedでも宣言するとエラーになる。
このため、watchプロパティを使って変更有無を監視し、値を更新するよう設定する。
▼propsとcomputedの併用で発生するエラー
[Vue warn]: The computed property "value" is already defined as a prop.
▽コード事例
親から引き継いだデータはpropsで宣言する必要があるため、computedで再度セットすると重複となる。
<script>
export default {
props:{
value: {}
},
data(){
return{
childText: undefined
}
},
computed:{
value:{
get(){return this.value},
set(x){this.value = x}
}
}
}
</script>
watchを使ったセッター
<script>
export default {
props:{
value: {}
},
watch:{
value:{
immediate: true,
handler(x){
this.childText = x
}
}
}
}
</script>
watchプロパティの中でpropsで定義した変数valueを監視している。
・immediate: true
これがあるとページロードの段階からvalueの内容が適用される。
逆に、これがないと、なんらかの変化があるまで受け渡されたデータは表示されない。
・handler(引数){処理}
指定した変数のネストした値の変化も監視する。
handlerがない場合は、指定した変数のみで入れ子になったデータの変更は感知しない。
・this.childText = x
変数valueの値を引数xで渡して、別の変数'childText'に代入している。
大元の変数(value)を直接編集せずに間接的に変更しているためsetterの役割となる。
## フルコード
以下のような親となるparents.vueと子となるchild.vueでデータを受けわたす例。
<template>
<div>
<childTemplate v-model="text" />
</div>
</template>
<script>
import childTemplate from "./child"
export default {
components:{
childTemplate
},
data(){
return {
text: 'Default message'
}
}
}
</script>
・import childTemplate from "./child"
child.jsのファイルをテンプレート名childTemplateでインポート。
実際に使う場合は、componentsプロパティで宣言することも必要。
.jsや.vueなど拡張子は省略可能。
・<childTemplate v-model="text" />
v-modelを使って、子テンプレート(childTemplate)にデータを渡す。
inputタグにv-modelを使った場合、変数はvalueになる。
<template>
<div>
<input v-model="childText">
<p>・childText: {{childText}}</p>
</div>
</template>
<script>
export default {
props:{
value: {}
},
data(){
return{
childText: undefined
}
},
watch:{
value:{
immediate: true,
handler(x){
this.childText = x
}
}
}
}
</script>
・props:{ value: {} }
propsで親から受け取った変数を宣言する。データ受け渡しで必須の記述。
・childText: undefined
setterで大元の変数を代入する別の変数を用意しておく。
あとはwatchプロパティで変数valueを監視し、監視中の変数を上で宣言した変数に代入すれば完了。
↓ テキスト編集
想定通りデータバインディングができている。