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


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>



▼初期状態



▼文字入力後

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

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

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


immediate: true

(子)TextField.vue
  watch:{
    text:{
      //初期値からデータ連動
      immediate: true,
      handler(a){
        this.$emit('childChange', a)
      },
      deep: true
    }
  }
}