Vuetifyの「v-text-field」コンポーネントを使用して、計算処理を行っていました。その過程で、計算がうまくいかないことがありました。
何がまずかったのか、どうすればいいかをまとめました。
開発環境
os | windows11 |
node | v20.11.1 |
npm | 10.5.0 |
Vue | 3.4.21 |
Vuetify | 3.6.7 |
エディター | VS Code |
経緯
以下のように、テキストボックスに入力された数値をもとに計算を行います。期待値は「40」ですが、「3010」になってしまっています。
以下は、該当箇所のコードです。
<script setup lang="ts>
const pattern1 = ref(1);
</script>
<template>
<v-text-field v-model="pattern1" label="テキストボックス" width="150" bg-color="red"></v-text-field>
<p>{{ pattern1 }} + 10 = {{ pattern1 + 10 }}</p>
</template>
「v-model」でバインドされた値は、文字列として扱われます。初期値に数値の「1」を設定しているため、初期表示時は「number型」ですが、1文字でもテキストボックスに入力するとすぐに「pattern1」定数の型は「文字列」に変わってしまいます。
数値として扱う方法
結果
まずは、以下をご覧ください。パターン2もしくはパターン3の方法で正しく計算することができました。
それではうまくいく2つのパターンについて見ていきましょう。
パターン2
パターン2では、「v-text-field」コンポーネントを使用します。この時「v-model」を使ってバインドするわけですが、その際に「number」修飾子を付与します。こうすることで、テキストボックスに入力された値を文字列ではなく数値型として扱うことができます。
<v-text-field v-model.number="pattern2" suffix="万円" label="パターン2"></v-text-field>
パターン2の欠点は、数値以外の文字列も入力できてしまうことにあります。「1aaa」のように先頭が数値の場合は、後続の数値以外の文字はすべて無視されます。一方、「aaa1」のように先頭が数値以外の文字列の場合は、そのまま文字列としてバインドされてしまいます。
幸い、「v-text-field」には「rules」というプロパティがあります。数値以外の文字が入力された場合に警告メッセージを出して、入力された文字を無視するようなチェック処理を指定するとよいでしょう。
const isNumber = (input) => {
if (isNaN(input)) {
return '数値を入力してください'
} else {
return true
}
}
<v-text-field v-model.number="pattern2" suffix="万円" label="パターン2"
rules="[isNumber]"></v-text-field>
「NaN」は「Not-A-Number(数値ではない)」を意味します。そのため、「isNan」関数に数値(に変換できるものを含む)を渡したときに「false」となります。
今回の例は、警告メッセージを出すだけでしたが、数値以外の場合は入力内容をリセットするなど要件に応じてカスタマイズするとよいと思います。
パターン3
パターン3では、「v-number-input」コンポーネントを使用します。
<v-number-input v-model.number="pattern3" label="パターン3"></v-number-input>
「v-number-input」では、数値以外は入力できません。そのため、数値のみ入力してほしい時などには非常に有用なコンポーネントです。
また、「v-text-field」がベースになっています。suffix(パターン2でいう万円)の追加やルールの追加も同様に可能です。
最後に
Vuetifyでは、数値のみを取り扱いたい要望にぴったりのコンポーネントがちゃんと用意されていました。改めてVuetifyのカバー範囲の広さを実感できました。
コメント