Vue.jsで数値が絡むフォーム入力バインディングを行うときにハマったことについて解説していきます。
目的の処理
- 数値を入力するフォーム(
type="number"
)を3つ作成 - この3つのフォームに与えられた数値の合計を
total
としてフロントに反映
この処理を行うためにVue.jsにあるフォーム入力バイディング(v-model
)と算出プロパティ(computed
)を使用していきます。
間違ったコード
<template>
<div>
<div>
<label for="first-num">First: </label>
<input type="number" name="first-num" v-model="firstNum">
</div>
<div>
<label for="second-num">Second: </label>
<input type="number" name="second-num" v-model="secondNum">
</div>
<div>
<label for="third-num">Third: </label>
<input type="number" name="third-num" v-model="thirdNum">
</div>
<div>total: {{ totalNum }}</div>
</div>
</template>
<script>
export default {
data() {
return {
firstNum: 0,
secondNum: 0,
thirdNum: 0,
}
},
computed: {
totalNum() {
return this.firstNum + this.secondNum + this.thirdNum
}
}
}
</script>
これは、実際に最初に書いたコードです。
初期値0の3つのデータ(firstNum
, secondNum
, thirdNum
)をv-model
を用いてフォームの入力の変更を反映、compouted
でそれぞれの合計をtotalNum
として処理をするという内容になっています。
一見正しい記述内容に見えますが、これを確認してみると、以下のようになります。
間違いの原因
この間違った挙動は、v-model
が返す値が要因となっています。
公式ドキュメントによると、v-model
は入力された値の形式にかかわらず文字列として返して性質があるようです。
今回の処理で説明すると、フォームの形式がtype="number"
になっているのにもかかわらずv-model
で返ってくる値が文字列になってしまったために、totalNum
内で、
return 2 + 3 + 7
というような処理をしたかったのに実際は、
return "2" + "3" + "7"
このような処理になってしまったということです。
解決策
公式ドキュメントを参考に以下のように修正します。
<template>
<div>
<div>
<label for="first-num">First: </label>
<input type="number" name="first-num" v-model.number="firstNum">
</div>
<div>
<label for="second-num">Second: </label>
<input type="number" name="second-num" v-model.number="secondNum">
</div>
<div>
<label for="third-num">Third: </label>
<input type="number" name="third-num" v-model.number="thirdNum">
</div>
<div>total: {{ totalNum }}</div>
</div>
</template>
<script>
export default {
data() {
return {
firstNum: 0,
secondNum: 0,
thirdNum: 0,
}
},
computed: {
totalNum() {
return this.firstNum + this.secondNum + this.thirdNum
}
}
}
</script>
v-model
に末尾に.number
を追加することで、v-model
は数値として値を返してくれるようになります。
これで目的の処理になりました!
結論
Vue.jsの標準で搭載されているv-model
はバイディングを行う際にとても便利な機能ですが、仕組みや使い方を間違ってしまうと、このような初歩的な部分でつまづいてしまいそうになりますね...
これからは、公式ドキュメントの参照を心がけます!
同じようなところでつまづいている方々の参考になれたならなと思います。
参考サイト