惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Spread Privacy
Spread Privacy
K
Kaspersky official blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Forbes - Security
Forbes - Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
The Last Watchdog
The Last Watchdog
SecWiki News
SecWiki News
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
Security Archives - TechRepublic
Security Archives - TechRepublic
S
Secure Thoughts
WordPress大学
WordPress大学
Microsoft Security Blog
Microsoft Security Blog
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
Security Latest
Security Latest
TaoSecurity Blog
TaoSecurity Blog
Cyberwarzone
Cyberwarzone
S
SegmentFault 最新的问题
Cloudbric
Cloudbric
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
N
Netflix TechBlog - Medium
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
H
Hacker News: Front Page
C
Cybersecurity and Infrastructure Security Agency CISA
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
AWS News Blog
AWS News Blog
AI
AI
G
GRAHAM CLULEY
IT之家
IT之家
P
Privacy & Cybersecurity Law Blog
L
Lohrmann on Cybersecurity
Last Week in AI
Last Week in AI
D
Docker
Recent Announcements
Recent Announcements
O
OpenAI News
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
S
Security @ Cisco Blogs
T
Troy Hunt's Blog
C
Check Point Blog
博客园 - 三生石上(FineUI控件)
A
About on SuperTechFans
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
N
News and Events Feed by Topic

Dmitri Pavlutin Blog

Pure Functions in JavaScript: A Beginner's Guide Record Type in TypeScript: A Quick Intro How to Write Comments in React: The Good, the Bad and the Ugly 4 Ways to Create an Enum in JavaScript React forwardRef(): How to Pass Refs to Child Components TypeScript Function Types: A Beginner's Guide Mastering Vue refs: From Zero to Hero Environment Variables in JavaScript: process.env 5 Must-Know Differences Between ref() and reactive() in Vue How to Destructure Props in Vue (Composition API) Triangulation in Test-Driven Development How to Use nextTick() in Vue Programming to Interface Vs to Implementation A Smarter JavaScript Mapper: array.flatMap() Array Grouping in JavaScript: Object.groupBy() How to Access ES Module Metadata using import.meta JSON Modules in JavaScript How to Trim Strings in JavaScript TypeScript Function Overloading How to Debounce and Throttle Callbacks in Vue How to Show/Hide Elements in Vue Sparse vs Dense Arrays in JavaScript How to Fill an Array with Initial Values in JavaScript Covariance and Contravariance in TypeScript What are Higher-Order Functions in JavaScript? How to Use TypeScript with React Components Index Signatures in TypeScript How to Use React useReducer() Hook unknown vs any in TypeScript A Guide to React Context and useContext() Hook How to Use Promise.any() 2 Ways to Remove a Property from an Object in JavaScript 'return await promise' vs 'return promise' in JavaScript How to Use Promise.allSettled() How to Use fetch() with JSON JavaScript Promises: then(f,f) vs then(f).catch(f) What is a Promise in JavaScript? How to Use Promise.all() A Simple Guide to Component Props in React Don't Stop Me Now: How to Use React useTransition() hook A Simple Explanation of JavaScript Variables: const, let, var ES Modules Dynamic Import How to Memoize with React.useMemo() How to Cleanup Async Effects in React Why Math.max() Without Arguments Returns -Infinity How to Debounce and Throttle Callbacks in React Don't Confuse Function Expressions and Function Declarations in JavaScript How to Use ES Modules in Node.js Solving a Mystery Behavior of parseInt() in JavaScript How to Use Array Reduce Method in JavaScript 3 Ways to Merge Arrays in JavaScript A Guide to Jotai: the Minimalist React State Management Library The Difference Between Values and References in JavaScript How to Implement a Queue in JavaScript A Helpful Algorithm to Determine "this" value in JavaScript React useRef() Hook Explained in 3 Steps 7 Interview Questions on "this" keyword in JavaScript. Can You Answer Them? How to Greatly Enhance fetch() with the Decorator Pattern 7 Interview Questions on JavaScript Closures. Can You Answer Them? What's a Method in JavaScript? array.sort() Does Not Simply Sort Numbers in JavaScript How to Solve the Infinite Loop of React.useEffect() The New Array Method You'll Enjoy: array.at(index) What's the Difference between DOM Node and Element? Why Promises Are Faster Than setTimeout()? Everything About Callback Functions in JavaScript How React Updates State 5 Mistakes to Avoid When Using React Hooks 5 Best Practices to Write Quality JavaScript Variables Type checking in JavaScript: typeof and instanceof operators 3 Ways to Check if a Variable is Defined in JavaScript React Forms Tutorial: Access Input Values, Validate, Submit Forms Prototypal Inheritance in JavaScript How to Timeout a fetch() Request How to Learn JavaScript If You're a Beginner A Simple Explanation of React.useEffect() A Simple Explanation of JavaScript Iterators How to Use React Controlled Inputs Everything about null in JavaScript How to Use Fetch with async/await Getting Started with Arrow Functions in JavaScript An Interesting Explanation of async/await in JavaScript Front-end Architecture: Stable and Volatile Dependencies Is it Safe to Compare JavaScript Strings? How to Access Object's Keys, Values, and Entries in JavaScript What Actually is a String in JavaScript? 3 Ways to Shallow Clone Objects in JavaScript (w/ bonuses) Checking if an Array Contains a Value in JavaScript JavaScript Event Delegation: A Beginner's Guide How to Parse URL in JavaScript: hostname, pathname, query, hash 3 Ways to Detect an Array in JavaScript How to Get the Screen, Window, and Web Page Sizes in JavaScript 3 Ways to Check If an Object Has a Property/Key in JavaScript How to Compare Objects in JavaScript Object.is() vs Strict Equality Operator in JavaScript Own and Inherited Properties in JavaScript 5 Differences Between Arrow and Regular Functions How to Use Object Destructuring in JavaScript Your Guide to React.useCallback() 5 JavaScript Scope Gotchas
How to Use v-model to Access Input Values in Vue
Dmitri Pavlutin · 2023-03-17 · via Dmitri Pavlutin Blog

v-model is handy to access and modify input fields values.

<input v-model="myRef" /> enables the two-way binding. When user types into the input then the ref changes, and vice-versa when the ref is changed programmatically then the input value changes.

Let's see how to use v-model to bind form inputs in Vue 3.

Table of Contents

  • 1. Binding a form input
  • 2. v-model vs v-bind
    • 2.1 Emulating v-model
  • 3. Binding using reactive()
  • 4. Binding different input types
    • 4.1 Textareas
    • 4.2 Select fields
    • 4.3 Checkboxes
    • 4.4 Radio buttons
  • 5. v-model modifiers
    • 5.1 trim
    • 5.2 number
    • 5.3 lazy
  • 6. Conclusion

1. Binding a form input

Let's implement a component that renders an input field with the initial value 'Unknown'. The value that user introduces into the input field renders on the screen.

v-model fits nicely to implement such a component. Connecting v-model with the input field requires 2 simple steps:

  1. const text = ref(): reactive value to serve as a data bus for v-model
  2. v-model="text": add v-model to the input field tag assigned with text.


<script setup>

import { ref } from 'vue'

const text = ref('Unknown') // Step 1: create data bus

</script>

<template>

<!-- Step 2: assign data bus to v-model -->

<input v-model="text" type="input" />

<div>{{ text }}</div>

</template>


Open the demo.

Open the demo. The input field contains initially 'Unknown'. Type something into the input field: and both the input value and the text on the screen update.

v-model="text" is two-way data binding in Vue.

Vue two way binding

The first direction of flow happens during the initialization. The input value is initialized with 'Unknown'text's initial value.

The second direction of flow occurs when you type into the input field. v-model takes the value of the input and updates text ref with it.

2. v-model vs v-bind

v-bind is another data binding mechanism in Vue:


<input v-bind:value="text" type="text" />


which can be shortened to:


<input :value="text" type="text" />


What is the difference between v-model and :value? <input :value="value" /> is a one-way data flow mechanism.

To understand the difference let's change the previous example's input tag from v-model="text" to :value="text":


<script setup>

import { ref } from 'vue'

const text = ref('Unknown')

</script>

<template>

<input :value="text" type="input" />

<div>{{ text }}</div>

</template>


Open the demo.

Open the demo. The input field is initialized with 'Unknown'.

Type some characters into the input field... and the text rendered on the screen always stays the same — 'Unknown'. text ref is not updated when the input field changes.

:value="text" makes data flow in one direction only: from the text ref to the input field. Changing the input field value, however, doesn't change text ref.

Vue one-way binding

In conclusion, v-model enables a two-way data flow, while :value enables a one-way data flow.

2.1 Emulating v-model

Despite the difference, v-model can be emulated using :value and @input:


<input v-model="text" type="text" />


can be expressed as:


<input :value="text" @input="text = $event.target.value" type="text" />


The following code doesn't use v-model, but still has two-way data flow working:


<script setup>

import { ref } from 'vue'

const text = ref('Unknown')

</script>

<template>

<input

:value="text"

@input="text = $event.target.value"

type="input"

/>

<div>{{ text }}</div>

</template>


Open the demo.

Open the demo and type some characters into the input. The two-way binding is working correctly.

The regular binding :value="text" enables the first flow.

@input="text = $event.target.value" updates text when user types into the input field gets triggered. That's the second flow.

3. Binding using reactive()

reactive() is a Vue reactivity API that makes an object reactive.

The main difference between ref() and reactive() is that refs can store primitives and objects, while reactive() accepts only objects. And reactive() object can be access directly (without .value property as in the case of refs).

Binding a reactive object to form inputs is handy when you have a lot of inputs. You can bind each input field with a specific property of the reactive object.

Let's implement a form having first and last name inputs, and bound these to a reactive object's properties:


<script setup>

import { reactive } from 'vue'

const person = reactive({ firstName: 'John', lastName: 'Smith' })

</script>

<template>

<input v-model="person.firstName" type="input" />

<input v-model="person.lastName" type="input" />

<div>Full name is {{ person.firstName }} {{ person.lastName }}</div>

</template>


Open the demo.

const person = reactive({ firstName: '', lastName: '' }) creates a reactive object.

v-model="person.firstName" binds with the first name property, as well as v-model="person.lastName" binds to the last name property.

Open the demo. Type into the first or last name inputs, and you'll see that the rendered text changes according to the name you type.

Vue two-way binding reactive

Pretty nice! Properties of a reactive object can serve as data buses for v-model. Use this approach to bind many input fields.

4. Binding different input types

Many other input types like select, textarea, checkboxes, radio buttons can bind using v-model. Let's explore them.

4.1 Textareas

Binding a textarea to a ref is straightforward. Just use v-model on the textarea tag <textarea v-model="longText" />:


<script setup>

import { ref } from 'vue'

const longText = ref("Well... here's my story. One morning...")

</script>

<template>

<textarea v-model="longText" />

<div>{{ longText }}</div>

</template>


Open the demo.

4.2 Select fields

The select (aka dropdown) field offers user a pre-defined set of options to choose from.

Binding a select is simple: <select v-model="selected" />:


<script setup>

import { ref } from 'vue'

const employeeId = ref('2')

</script>

<template>

<select v-model="employeeId">

<option value="1">Jane Doe</option>

<option value="2">John Doe</option>

<option value="3">John Smith</option>

</select>

<div>Selected id: {{ employeeId }}</div>

</template>


Open the demo.

employeeId is the ref bound to the select and will get the value of the option being selected.

Because employeeId ref is initialized with '2', John Doe option is initially selected.

When you select another option, you can see that employeeId updates with the newly selected option value.

If the select options do not have value attributes, then the binding works with the text of the options:


<script setup>

import { ref } from 'vue'

const employee = ref('Jane Doe')

</script>

<template>

<select v-model="employee">

<option>Jane Doe</option>

<option>John Doe</option>

<option>John Smith</option>

</select>

<div>Selected: {{ employee }}</div>

</template>


Open the demo.

Now the binding works directly with the textual value of the options. If you'd select the second option, then employee ref is assigned with 'John Doe'.

4.3 Checkboxes

Thanks to v-model binding checkboxes is easy:


<input ref="checked" type="checkbox" />


checked ref is assigned with a boolean value indicating whether the checkbox is checked or not.

Let's create a checkbox that bounds to a checked ref:


<script setup>

import { ref } from 'vue'

const checked = ref(true)

</script>

<template>

<label><input v-model="checked" type="checkbox" />Want a pizza?</label>

<div>{{ checked }}</div>

</template>


Open the demo.

checked ref is initialized with true and thus initially the checkbox is checked. Checking or unchecking the checkbox updates checked ref correspondingly with true or false. No rocket science here.

To customize the checked/unchecked binding to other values that a boolean, then Vue offers 2 Vue-specific attributes on the checkbox:


<input

v-model="checked"

true-value="Yes!"

false-value="No"

/>


Now checked is assigned to 'Yes!' (as true value) or 'No' (as false value) string depending on the checkbox status.

Let's modify the previous example to use the custom values 'Yes!' and 'No':


<script setup>

import { ref } from 'vue'

const answer = ref('Yes!')

</script>

<template>

<label>

<input v-model="answer" type="checkbox" true-value="Yes!" false-value="No" />

Want a pizza?

</label>

<div>{{ answer }}</div>

</template>


Open the demo.

answer now can have either 'Yes!' or 'No' depending on the checkbox's check status.

4.4 Radio buttons

To bind a group of radio buttons apply to the group the same the same bus binding v-model="option":


<input type="radio" v-model="option" value="a" />

<input type="radio" v-model="option" value="b" />

<input type="radio" v-model="option" value="c" />


For example, let's implement a radio buttons group to select the color of a T-shirt:


<script setup>

import { ref } from "vue"

const color = ref("white")

</script>

<template>

<label><input type="radio" v-model="color" value="white" />White</label>

<label><input type="radio" v-model="color" value="red" />Red</label>

<label><input type="radio" v-model="color" value="blue" />Blue</label>

<div>T-shirt color: {{ color }}</div>

</template>


Open the demo.

Initially, the White radio is selected because the color ref is initialized with 'white'.

Click on any other T-shirt color, and the color ref changes according to the selected color.

value attribute of the radio is bindable: you can use :value. That is helpful when the list of options comes from an array, for example:


<script setup>

import { ref } from "vue"

const color = ref("white")

const COLORS = [

{ option: "white", label: "White" },

{ option: "black", label: "Black" },

{ option: "blue", label: "Blue" },

]

</script>

<template>

<label v-for="{ option, label } in COLORS" :key="option">

<input type="radio" v-model="color" :value="option" /> {{ label }}

</label>

<div>T-shirt color: {{ color }}</div>

</template>


Open the demo.

5. v-model modifiers

On top of doing a wonderful job with binding form inputs, v-model has an additional feature called modifier.

A modifier is a piece of logic applied to v-model to customize its behavior. A modifier is applied to v-model by using a dot syntax v-model.<modifier>, for example v-mode.trim.

By default Vue offers 3 modifies: trim, number, and lazy.

5.1 trim

Trimming a string means removing whitespaces from the beginning and the end of the string. For example, trim applied to ' Wow! ' results in 'Wow!'.

Vue v-model.trim

v-model.trim modifier trims the input field value before assinging the value to the bound ref.


<script setup>

import { ref } from 'vue'

const text = ref('')

</script>

<template>

<input v-model.trim="text" type="text" />

<pre>"{{ text }}"</pre>

</template>


Open the demo.

Open the demo. Type a value that starts or ends with spaces, e.g. ' Hi! '. You'll see that the rendered text 'Hi!' doesn't have spaces on both ends.

5.2 number

v-model.number modifier applies a number parser on the input field value.

v-model.number="number" assigns to number a real number if the user introduced a value that can be parsed to a number. In other cases, if the introduced value is not numeric, number ref is just assigned to the original string.

Vue v-model.number


<script setup>

import { ref } from "vue";

const number = ref("");

</script>

<template>

<input v-model.number="number" type="text" />

<div>{{ typeof number }}</div>

</template>


Open the demo.

When you introduce '345' into the input, then number ref becomes 345 (a number). Value parsing happens automatically.

But if you introduce a non-numeric value into the input, like 'abc', then number ref is assigned with the same value 'abc'.

5.3 lazy

By default, v-model uses "input" event to determine when to update the bound ref. But using the modifier v-model.lazy you can alter the event to be "change" event.

What's the main difference between input and change events?

input is triggered every time you keypress in the input field.

change, however, is triggered only when the input field looses focus. Typing into the input field does not trigger change.

Vue v-model.lazy

The following example uses lazy binding:


<script setup>

import { ref } from 'vue'

const text = ref('Unknown')

</script>

<template>

<input v-model.lazy="text" type="input" />

<div>{{ text }}</div>

</template>


Open the demo.

Open the demo and type a few characters into the input. The rendered text stays the same: Unknown.

Now click somewhere outside of the input field to make it lose focus. The rendered text updates to the value that you introduced earlier.

If you have a form with many input fields and heavy state, you can apply the lazy modifier to disable realtime reactivity as the user types. That could prevent page freezes during typing.

6. Conclusion

From all the details you've read, remember just one.

v-model binds form inputs to refs or reactive objects.

Binding is performed in 2 easy steps:

  • First, create the ref const text = ref('').
  • Second, assign the ref to the v-model attribute: <input v-model="text" type="text" />

text ref is kept in sync (bound) with the input field value.

Do you have any questions about v-model?