LoginSignup
1
2

More than 3 years have passed since last update.

watchプロパティで入力内容を即時反映する方法。子から親へのデータ受け渡し

Last updated at Posted at 2020-10-27

watchプロパティで入力内容を即時反映する方法。子から親へのデータ受け渡し

watchプロパティを使うと画面上の変更内容をリアルタイムで検知し、設定した処理を実行することができる。

watchプロパティを使う手順

①変数を定義する
 ↓
②変数に対してwatachプロパティを設定する

watchプロパティは変数の変更を感知するため、変更内容を監視する変数を指定する。



※注意点
・watchプロパティの中で監視する変数を指定。
  ┗ 変数名:function(){処理}

・変数内のネストしたデータを監視する場合は追加設定が必要。
  ┗ 関数を「handler(){}」にする。
  ┗ 「deep: true」を設定する。


watchプロパティの使い方(ネストしてない変数の監視)

  watch:{
     プロパティ名: function(){
       処理
     }
  }

実例

(子)TextField.vue
<template>
<div>
  <v-col
    cols="12"
    sm="3">
    <v-text-field
     v-model="text" />
  </v-col>
</div>
</template>

<script>
export default {
  data(){
    return{
      //①監視する変数を定義
      text: "初期値"
  },
  watch:{
    //②変数に対してwatchプロパティを設定
    //textの値が変わったら以下処理を実行。
    text:
      function (a){
        this.$emit('childChange', a)
    }
  }
}
</script>

関数内のthis.$emit('childChange', a)
 ┗ 関数内でプロパティを自分の呼び出す場合はthisが必要。
 ┗ $emitは子から親にデータを渡す
 ┗ $emit('親に渡すメソッド名', 引数)
   ┗ 引数は任意
   ┗ 引数には監視している変数が入る



▼引数のメリット
引数を使わずにデータを指定して渡す方法もあるが、引数を使った記述の方がより簡易的。

引数あり
  watch:{
    text:
      function (a){
        this.$emit('childChange', a)
    }
  }
引数なし(データを直接指定)
  watch:{
    text:
      function (){
        this.$emit('childChange', this.text)
    }
  }
(親)parent.vue
<template>
  <v-app>
    <TextField
    <!--子からイベントを受け取り、親のイベントに引き継ぐ-->
    @childChange="parentChange"
     />

    <p>
    ・v-modelのデータ:  {{text}}
    </p>
  </v-app>
</template>

<script>
import TextField from "./TextField"

export default {
  name: "Parent",
  components:{
    TextField
  },
  data(){
    return{
      text:'初期値'
    }
  },
  methods:{
    //親のイベントを実行
    parentChange(text){
      this.text = text
      console.log("text-filedが変更されました")
    }
  }
}
</script>

これで、text-fieldへの入力値がリアルタイムで反映される。


ネストした変数データの監視

変数がネストしている場合、以下2つの設定が必要。

(1) functionをhandlerに変更
(2) deep: true を設定

※watchプロパティの中が入れ子になるため、追加で{}が必要。

  watch:{
    プロパティ名:{ 
      handler(){
        処理
      },
      deep: true
    }
  }


実例

(子)TextField.vue
<template>
<div>
  <v-col
    cols="12"
    sm="3">
    <v-text-field
     v-model="text.sub" />
  </v-col>
</div>
</template>

<script>
export default {
  data(){
    return{
      //①監視する変数を定義(入れ子)
      text: {
        first: "初期値",
        sub: "subテキスト"}
    }
  },
  watch:{
    //②変数に対してwatchプロパティを設定
    text:{ 
      handler(a){
        this.$emit('childChange', a)
      },
      deep: true
    }
  }
}
</script>
parent.vue
<template>
  <v-app>
    <TextField
    <!--子からイベントを受け取り、親のイベントに引き継ぐ-->
    @childChange="parentChange"
     />

    <p>
    ・v-modelのデータ:  {{text}}
    </p>
  </v-app>
</template>

<script>
import TextField from "./TextField"

export default {
  name: "Parent",
  components:{
    TextField
  },
  data(){
    return{
      text:'初期値'
    }
  },
  methods:{
    parentChange(text){
      //受け取った入れ子の変数のsubを使う
      this.text = text.sub
      console.log("text-filedが変更されました")
    }
  }
}
</script>



▼初期状態

image.png



▼文字入力後

image.png
image.png

文字を入力する毎に、親で設定したメソッドが実行されている。

変更があったタイミングでwatchが作動するため、初期値は反映されていない。

immediate: trueを追加で記述することで、初期値から反映することができる。


immediate: true

(子)TextField.vue
  watch:{
    text:{
      //初期値からデータ連動
      immediate: true,
      handler(a){
        this.$emit('childChange', a)
      },
      deep: true
    }
  }
}
image.png
1
2
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
1
2