Vue入力値変更と変化の検出 ＆ 子から親にデータを渡す方法（v-model、@change）

#Vue入力値変更と変化の検出 ＆ 子から親にデータを渡す方法（v-model、v-on:change）

自分のテンプレート内での変化を検出するパターンと、子テンプレートでの変化を検出し親に情報を渡すパターンの２つを考えてみる。


##自分のテンプレート内での変化を検出

###手順

```:
①タグにv-modelを設定する (v-model="変数")
　↓
②dataオプションで変数を定義する
　↓
③タグに@changeイベントを設定する（@change="イベント名"）
　↓
④methodsオプションで処理を定義する
```

①と②、③と④がそれぞれ対となる。

※注意点
・v-modelで指定した変数の値と画面入力が連動する
・「@」は「v-on:」の省略形
　 `@change` = `v-on:change`

<br>


```vue:vue
<template>
<div>
  <v-col
    cols="12"
    sm="3">
    <v-text-field
     <!--①v-modelを設定-->
    　v-model="text"
     
     <!--③changeイベントを設定-->
      @change="applyChanges" />
  </v-col>

  
  <p>
    <!--v-modelのデータ連動確認用-->
   ・v-modelのデータ: 　{{text}}
  </p>
</div>
</template>

<script>
export default {
  data(){
    return{
      //②v-model用の変数を定義
      text: "初期値"
    }
  },
  methods:{
    //④changeイベント用のメソッドを定義
    applyChanges(){
      console.log("text-filedが変更されました")
    }
  }
}
</script>
```

<br>
**実行結果の確認**

▼変更前の状態。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/2fb71a73-dcff-5b69-c630-4c825a7742a6.png)|
|:--|

<br>
▼変更後の状態

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/ad46318d-cb69-2d64-f17f-1d5bccd6fe96.png)|
|:--|

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/6ad07ccf-0075-cc21-af44-11d6bf771084.png)|
|:--|


v-modelでデータが連動。changeイベントが発火している。



<br>
##子から親へのデータ受け渡し

大まかな流れは、子テンプレでデータ発信を準備し、親側で受け取る用意をする。


```:
子：①タグにv-modelを設定 (v-model="変数")
　↓
子：②dataオプションで変数を定義
　↓
子：③タグに@changeイベントを設定（@change="イベント名"）
　↓
子：④methodsオプションで発信処理を定義 （★親に引き渡すイベントと変数）
　↓
親：⑤受け取ったイベント名を属性で定義し親のイベントに引き継ぐ　（@受けとたイベント名 = "親のイベント名"）
　↓
親：⑥methodsオプションで処理を定義 （引数で子の変数を受け取る）
　↓
親：⑦受け取ったデータをいれる変数を定義（dataオプション）
　↓
親：⑧受け取ったデータを画面上に表示

```

※注意点
・子のmethods内で、プロパティを呼び出す場合は「this」をつける。
　┗ this.$emit('受け渡すメソッド名', 変数)
　┗ this.プロパティ名　


<br>

###実例

```vue:(子)TextField.vue
<template>
<div>
  <v-col
    cols="12"
    sm="3">
     <!--①v-modelを設定-->
    　v-model="text"
     
     <!--③changeイベントを設定-->
      @change="applyChanges" />
  </v-col>
</div>
</template>

<script>
export default {
  data(){
    return{
      //②v-model用の変数を定義
      text: "初期値"
    }
  },
  methods:{
    //④methodsオプションで発信処理を定義 
    applyChanges(){
      //データを変数で渡すため変数を定義
      const text = this.text
      //第１引数でイベント名、第２引数で変数を渡す
      this.$emit('childChange', text)
    }
  }
}
</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:{
    //⑥methodsオプションで処理を定義 
    parentChange(text){
      this.text = text
      console.log("text-filedが変更されました")
    }
  }
}
</script>
```


<br>
**実施結果**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/97b4d64a-743d-f135-be8c-8dcadb77f75d.png)|
|:--|


<br>
**▼画面入力後**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/d2125ea2-563f-08ec-63bd-cef25371846e.png)|
|:--|

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/37ecec2e-edc6-18fc-0ec0-e7ef6ed18ae2.png)|
|:--|

v-modelで変更した値が適用されている。
親側で定義したメソッドも発火している。


ただし、上記いずれの例も、changeイベントでmethodを発火させるため、変更を確定（Enter）しないと反映されない。

入力内容を即時反映したい場合はwatchプロパティを使う。