mmag

ハマったことメモなど

v-modelを受け付けるカスタムコンポーネントの書き方の好み

Vue.js 2系を対象とします。

何がしたいかというと、

<my-great-text-input v-model="text" />

ということがしたい。

とりあえずドキュメントを見ると、以下のような方法が書いてある。

https://jp.vuejs.org/v2/guide/components.html#カスタムイベントを使用したフォーム入力コンポーネント

<template>
  <input type="text" :value="value" @input="updateText">
</template>

<script>
  export default {
    props: ['value'],
    methods: {
      updateText(e) {
        this.$emit('input', e.target.value)
      }
    }
  }
</script>

ただ、必ずしもこれしか方法がないわけではなくて

  • value プロパティを受け入れる
  • 新しい値と共に input イベントを送出する

を満たしていればOK。なので色々なパターンが考えられる。自分は双方向算出プロパティがスッキリしているように見えるマンなので

<template>
  <input type="text" v-model="innerValue">
</template>

<script>
  export default {
    props: ['value'],
    computed: {
      innerValue: {
        get() {
          return this.value
        },
        set(val) {
          this.$emit('input', val)
        }
      }
    }
  }
</script>

というのが好き。

テーマはFB matteをベースにしてます。作者さんに感謝を込めて。