どーも、ぐるたか@guru_takaです。
Vueにて、子コンポーネント内にあるInputの値を、親コンポーネントにバインドさせる方法をまとめました。
よくある間違いも紹介しています。参考になれば幸いです!
v-modelに親からデータ渡すだけではアウト!
以下のコードはやりがちですが、うまく動きません。
子コンポーネント
引用:Vue.js:v-modelと$emitを使ってデータを読み書きする子コンポーネントをつくる
<template>
<input v-model="value" />
</template>
<script>
export default {
props: ['value']
}
</script>
なぜなら、value
は親から渡されたprops
なので、Read onlyだからです。
子コンポーネントで変更したい値を親コンポーネントに渡すには、一工夫、必要になります。
親子間でInput内の値をバインドさせる方法
まずはコードから!
子コンポーネント
<template>
<input
:value="value"
@input="$emit('input', $event.target.value)"
/>
</template>
<script>
export default {
props: ['value']
}
</script>
親コンポーネント
<template>
<div>
<InputChild
:value="value"
@input="value = $event"
></InputChild>
</div>
</template>
<script>
import InputChild from '@/components/InputChild'
export default {
components: {
InputChild
},
data() {
return {
value: ''
}
},
}
</script>
以下の記事を参考にしています。
参考
Vue.js:v-modelと$emitを使ってデータを読み書きする子コンポーネントをつくるQiita
簡単な解説
v-modelの仕組み
v-modelは以下のコードのように分解できます。
<syntax-sugar v-model="cup"></syntax-sugar>
<syntax-sugar :value="cup" @input="val => cup = val"></syntax-sugar>
v-model
は、Input内の値が変更されると、@input
が発火し、値が更新される仕組みになっています。
なので、親子間でデータをバインドさせる時は、v-model
ではなく、:value
と@input
をうまく使ってあげれば、良いのです!
$event
と$event.target.value
について
$event
と$event.target.value
は公式に、お作法が載っています。
Inputタグの場合
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
オリジナルのコンポーネントの場合
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
簡単にまとめると
- inputタグの場合は、
$event.target.value
で値を更新 - 独自コンポーネントの場合は、
$event
で値を更新
になります。
参考 コンポーネントの基本Vue.js最後に
以上になります。個人的ですが、v-model
の中身や@input
の仕組みも理解できて良かったです!
ぜひお試しください!
[…] […]