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

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


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


##watchプロパティを使う手順

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

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




<br>
※注意点
・watchプロパティの中で監視する変数を指定。
　　┗ 変数名:function(){処理}
 
・変数内のネストしたデータを監視する場合は追加設定が必要。
　　┗ 関数を「handler(){}」にする。
　　┗ 「deep: true」を設定する。




<br>
##watchプロパティの使い方（ネストしてない変数の監視）

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


###実例

```vue:(子)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('親に渡すメソッド名', 引数)
　　　┗ 引数は任意
　　　┗ 引数には監視している変数が入る


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

```js:引数あり
  watch:{
    text:
      function (a){
        this.$emit('childChange', a)
    }
  }
```

```js:引数なし(データを直接指定)
  watch:{
    text:
      function (){
        this.$emit('childChange', this.text)
    }
  }
```



```vue:(親)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への入力値がリアルタイムで反映される。





<br>
##ネストした変数データの監視
変数がネストしている場合、以下２つの設定が必要。

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

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


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


<br>
###実例

```vue:(子)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>
```


```vue: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>
```

<br>
**▼初期状態**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/27760761-c928-f01c-ada6-91ec350947ec.png)|
|:--|


<br>
**▼文字入力後**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/09388400-48f7-d47e-ca4b-71c92581d5d0.png)|
|:--|

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/696f7883-267e-ec7a-d1fd-646d5d81822a.png)|
|:--|

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

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

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


<br>
###immediate: true

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

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/30c11a59-f7d2-0d93-5dda-7b7c0c7d8068.png)|
|:--|