Vue を使った開発でありがちなのが、v-model
と Boolean 値が正しくバインドされない問題 です。特に input[type="checkbox"]
と組み合わせたときに、「true / false のはずが配列になってしまう」「意図せず文字列が入ってしまう」といった罠にハマるケースがあります。
本記事では、筆者が経験した v-model と Boolean 値の罠 を整理し、技術者向けの備忘録としてまとめます。
1. v-model と Boolean 値の基本
Vue における v-model
はフォーム要素との双方向バインディングを実現する便利な仕組みです。<input type="checkbox">
と組み合わせた場合、単一のチェックボックスなら Boolean 値、複数のチェックボックスなら配列を扱います。
図解:
[ 単一チェックボックス ] → true / false
[ 複数チェックボックス ] → ["A", "B"] のような配列
つまり「単一か複数か」で挙動が変わるのが落とし穴です。Boolean を期待しているのに配列が返ってきてしまうと、ロジックが破綻します。
2. 実際に遭遇したトラブル例
筆者が直面したのは以下のようなコードでした。
<template>
<input type="checkbox" v-model="isActive" value="true">
</template>
<script setup>
import { ref } from 'vue'
const isActive = ref(false)
</script>
一見正しく見えますが、value="true"
を書いたことで isActive
には Boolean ではなく [“true”] という配列 が入るようになってしまいました。
図解:
[☑ チェックON] → isActive = ["true"]
[□ チェックOFF] → isActive = []
「true / false」を期待していたのに実際には配列になり、条件分岐が正しく動作しなくなります。
3. なぜこうなるのか
Vue の仕組みとして、input[type="checkbox"]
に value
属性を指定すると 「複数選択を想定した挙動」 に切り替わります。結果、v-model
の対象が Boolean から配列に変化してしまいます。
つまり、Boolean を扱いたいときは value
を書いてはいけない というルールがあります。
図解:
✔ value あり → 配列モード
✖ value なし → Boolean モード
この仕様を知らないと、「なぜか true/false にならない」という混乱に陥ります。
4. 正しい書き方と修正例
Boolean 値を扱いたい場合、次のように書くのが正解です。
<template>
<input type="checkbox" v-model="isActive">
<p>状態: {{ isActive }}</p>
</template>
<script setup>
import { ref } from 'vue'
const isActive = ref(false)
</script>
これなら、チェック ON/OFF に応じて true / false
がきちんと反映されます。
図解:
[☑] → true
[□] → false
一方で配列を使いたい場合は、意図的に value
を付与し、複数のチェックボックスを組み合わせて使います。このように「用途に応じた正しい使い分け」が重要です。
5. チーム開発での注意点
この罠は個人開発ならすぐに気づけますが、チーム開発では 「誰かが value を付けたまま Boolean として使おうとしてしまう」 ケースが多発します。そのため以下のような工夫が有効です。
- コードレビューで
input[type="checkbox"]
のvalue
有無を確認 - ESLint ルールを導入し、不要な
value
を警告 - ドキュメントに「Boolean として使う場合は value を書かない」と明記
図解:
[レビュー] → value がある?
└─ YES → 配列モード、用途確認
└─ NO → Boolean モード、OK
このように仕組みを共有しておくことで、同じ罠にハマる開発者を減らせます。
6. まとめ
本記事では、Vue の v-model
と Boolean 値の扱いに潜む落とし穴を整理しました。
input[type="checkbox"]
は value 属性の有無で挙動が変わる- Boolean を期待するなら value を書かない
- 配列が欲しいなら value を明示的に使う
ちょっとした記述の違いが大きなバグにつながるため、チーム全体で仕様を理解して統一ルールを持つことが重要 です。
参考
- Vue.js 公式ドキュメント – v-model [https://vuejs.org/guide/essentials/forms.html]
- ESLint Plugin Vue – Recommended rules [https://eslint.vuejs.org/]