0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Vue】親から子へのデータ受け渡しでsetterを使う方法。v-modelとwatchプロパティの活用

Last updated at Posted at 2020-11-10

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でデータを受けわたす例。

parents.js
<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になる。


child.js
<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を監視し、監視中の変数を上で宣言した変数に代入すれば完了。

image.png

↓ テキスト編集

image.png

想定通りデータバインディングができている。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?