propsで受け取りデータ型を指定してinputもtype="number"してやれば堅牢なコンポーネントが作れるんじゃないかということでやってみたら、タイトルの通りの部分で詰まったのでまとめる。
ダメな例
基本的なpropsの受け取りデータ型の指定方法を使ってnullを追加してみる。
Vue.component('num-input', {
props: {
val: {
required: true,
type: [Number, null]
}
},
template: `
<input
type="number"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
すると、Right-hand side of 'instanceof' is not an object
と怒られる。
解決法
type
プロパティで指定するのではなく、独自のバリデーションを作ることで解決できる。
Vue.component('num-input'. {
props: {
val: {
required: true,
validator: prop => typeof prop === 'number' || prop === null
}
},
template: `
<input
type="number"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
とはいえ、HTMLでtype="number"
と指定してもstring
で渡される。(完全に忘れてて、[vue warm]でめっちゃ警告された…ありがとうvalidator)
親コンポーネントで使うときには、
<num-input v-model.number="val" />
という感じにv-modelにnumber修飾子を使えばnumber型
に変換された値が渡される。