はじめに。
v-modelは初心者には優しくないよねっていう話。
今年の4月から、晴れてフロントエンドエンジニアのキャリアがスタートしたわけですが、弊社ではVue3を使って開発をしています。Vue公式ドキュメントは読み漁り、いざ現場のコードを触るわけですが、わからないことだらけです。
私は以前勤めていた会社(某エンジニア育成会社)ではReactを学習していました。
何が違うって、大きく違うのは糖衣構文(シンタックスシュガー)だと思っています。
その糖衣構文のせいで、頭の整理が追いつかなくなるわけです。だって何が起きているか明示的に書かれていないんですから。そんな中からv-modelを題材にした記事を書いてみましたので、私と同じVueを触り始めたばかりという方にぜひ読んでいただき、共感してもらえたら嬉しいです。
優しくない理由
<input
① :value="text"
② @input="event => text = event.target.value">
上記のコードは何をしているのかすぐにわかりますよね。
① value属性にtextという変数がバインディングされているな〜
② input属性は、入力イベントを受け取ってその値を①のtextに代入しているな〜
うんうん、つまりは<input>という一つの要素内でイベントの値とその値の保持をしているんだな〜。こんな感じだと思います。では下記のコードはどうでしょうか?
<input v-model="text">
おい、何が起きてんだ!って、正直なりませんか?
(私はなりました。なんならこの間やっと理解しました)
v-modelを理解する
混乱の原因を特定する
v-bind v-onの両方を使って値を同期しているパターンと、v-modelとでは明らかな記述量の違いで混乱しますよね。確かにシンタックスシュガー(糖衣構文)で簡略化されてコードの量も減って、Vueを完全理解をしている人からしたら可読性が上がるかもしれないけど、初心者からすると端折られすぎて何してるか、裏で何が起こっているのかなんてパッと見じゃわかりづらいですよね。
裏で起きていることを理解する
まずは観察をしてみましょう。
<input
:value="text"
@input="event => text = event.target.value">
<input v-model="text">
①何が共通していて、②何が省略されたのかを見つけます。
-
textが共通している -
@input="event => XX = event.target.value"が省略されている
それぞれを言語化してみます。
① textはconst text = ref() の変数text のことで、リアクティブな値です。
② input要素の入力イベントをevent引数で受け取り、変数textにevent.target.valueを代入しています。
裏で何が起きているのかが明確になりましたね。
②で起きていることのほとんどを省略しているということです。
このほとんどとは、変数textに何かを代入するという処理以外は全て端折っているということです。実際には裏で起きていることで、目には見えていないというのが事実ですが。
新卒フロントエンジニアの腑に落ちた考え方
<input v-model="text">
フォーム要素(今回は<input>)はユーザーの入力によってイベントが発生します。イベントで得た値を利用する目的でフォーム要素を使いますよね。
つまりは"event => XX = event.target.value" という記述はフォーム要素で必ずと言っていいほど書かれるんです。ここで v-model というわけなんですよね。
なので、「あ、フォーム要素あるな〜」って見つけて、v-modelが使われていたならば、裏側では"event => XX = event.target.value"が行われていて、v-model="XX"にイベントで受け取った値が代入されるんだな〜って思ってください。
次回、カスタムコンポーネントの v-model を噛み砕く
基本的には、v-modelはフォーム要素全般で使用されますよね。
しかし、フォーム要素以外にも使えるようにするカスタムコンポーネントなんてものがあるということで、次回はこの題材を噛み砕こうと思っています。