v-model Modifiers
Shelf's form adds a book with 320 pages, and the "pages left" total becomes '32010'. Someone else saves a title as " Dune " with stray spaces, and the search cannot find it. Both bugs come from raw input text. Three small modifiers on v-model fix them at the source.
The rule
.numberconverts,.trimcleans,.lazywaits.
<input v-model.trim="title" placeholder="Title" />
<input v-model.number="pages" placeholder="Pages" />
<textarea v-model.lazy="notes"></textarea>.numberpasses the typed text throughparseFloat, so'320'becomes the number320. If the text cannot be parsed, such as'abc', the original string is kept, so still validate. An input withtype="number"gets this conversion automatically..trimremoves whitespace from both ends:" Dune "is stored as"Dune"..lazychanges when the ref updates. Normallyv-modelsyncs on everyinputevent, every keystroke. With.lazyit syncs on thechangeevent, which for a text box fires when the user leaves the field (or presses Enter in a single-line input). Good for fields that trigger expensive work, like validation that calls a server.
Modifiers combine: v-model.lazy.trim="title" waits until the user leaves, then stores the trimmed text.
Why the '32010' bug happened: in JavaScript, + with a string joins text. '320' + 10 is '32010', while 320 + 10 is 330. Converting at the input means every later calculation gets a real number.
The shortcut
For each field, ask three quick questions: "Is it a number? Could spaces sneak in? Must it update every keystroke?" Yes to the first → .number. Yes to the second → .trim. No to the third → .lazy.
Title
Not a number, spaces can sneak in, the live preview needs every keystroke.
v-model.trim.
A trap with .number: it does not guarantee a number. A user who types letters leaves a string in the ref. Check with typeof or Number.isFinite before trusting it.
Drills
Answer fast — trust the rule.
With v-model.number="pages", the user types 320. What is stored?
With v-model.number="pages", the user types abc. What is stored?
What does .lazy change?
The user types " Circe " into <input v-model.lazy.trim="title"> and tabs away. What is title?
Remember
.numberparses to a number,.trimremoves outer spaces,.lazyupdates on change instead of input.- Shortcut: ask "number? spaces? every keystroke?" for each field.
- Trap:
.numberkeeps unparseable text as a string, so still validate.
