4
2

More than 3 years have passed since last update.

【2020年版】v-modelをカスタムコンポーネントで実装しよう

Last updated at Posted at 2020-05-01

カスタムコンポーネントでv-model使いたいのに難しくない?

公式のドキュメントをみてもパッと見つからないし、いろんなゴリ押し代替案があってコードが煩雑になる…
と思いきやカスタムコンポーネントでもきちんとv-modelを利用する綺麗な手法がありました。

ほぼ備忘録的な記事ですが、お役に立てれば幸いです。

手順

すっ飛ばして見たい方はchildComponent.vueのコードを参照してください。

modelプロパティという物が公式の機能にありました…いつ実装されたんだろうか。
ともかくこれをコンポーネント内で使います。

parentComponent.vue内でchildComponent.vueを使う構成です。

parentComponent.vue
<template>
<div class="parentComponent">
    <childComponent v-model="modelvalue" />
</div>
</template>

<script>
import childComponent from 'path/to/childComponent'
export default {
    components: {
        childComponent,
    },
    data() {
        return {
            modelvalue: 'このプロパティをコンポーネント間で授受します。',
        }
    },
}
</script>
childComponent.vue
<template>
<div class="childComponent">
    <input @input="emitValue" :value="modelvalue" />
</div>
</template>

<script>
export default {
    //以下のmodelプロパティが今回の主役です。
    model: {
        prop: 'modelvalue',
        event: 'emit-text'
    },

    //propsプロパティにmodelプロパティ内で指定したプロパティを作成
    props: {
        modelvalue: {
            type: String //お好みのデータ型で
        }
    },

    methods: {
        emitText(e) {
            //modelプロパティで指定したイベントをthis.$emitメソッドで飛ばします。
            this.$emit('emit-text', e.target.value)
        },
    }
}
</script>

ちなみにtextarea要素でも同様に動作します。textarea要素には本来、value属性はありませんが上記のinput要素と同じようにvalueへmodelvalueをバインドすることでv-modelを利用できます。

注意点

  1. 上のコードを利用する場合、childComponent.vueinputタグ内にあるemitValueemitValue()と記述しないようにしてください。イベントがメソッドに渡されず動きません。
  2. childComponent.vuemodelプロパティのpropeventの値は文字列で指定してください。
4
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
4
2