The v-model
directive is one of the few directives that comes bundled with Vue.js. This directive allows for two-way data binding between our data and views.
With two-way data binding, when we update our data via input fields or other controls, we can modify the DOM (Document Object Model) without having to do DOM work.
In this article, you’ll explore how this directive works and use it for your own components.
v-model
Works InternallyFrom our knowledge of HTML, we know that input
, select
, and textarea
are the main ways we feed data to our application.
For v-model
to work, it expects the element or component in question to receive a prop (default is value
) and also emit an event (default is input
).
Depending on the element, Vue decides how to listen and handle the data. For input
elements, you might use v-model
like this:
<input v-model="email" />
v-model
translates to this:
<input :value="email" @input="e => email = e.target.value" />
Vue uses this expansion to handle textarea
, select
, and some other input
types.
For radio buttons and checkboxes, Vue uses their checked
prop and listens for their change
event.
For elements like select
tags and checkboxes that can accept multiple values, Vue will automatically return an array of selected values.
v-model
to Custom ComponentsTo let our component support v-model
two-way binding, the component needs to accept a value
prop and emit an input
event.
Let’s create a sample component called basic-input
. We’ll use Vue’s single file component:
<template>
<input @input="handleInput" />
</template>
<script>
export default {
prop: ['value'],
data () {
return {
content: this.value
}
},
methods: {
handleInput (e) {
this.$emit('input', this.content)
}
}
}
</script>
To support v-model
, the component accepts a value
prop and emits an input
event.
Use the component like this:
<basic-input v-model="email" />
With that, the custom component supports v-model
two-way binding.
v-model
prop
and event
Let’s take it a step further. We might not want to use the default event
and prop
needed to add v-model
support to our components. Thankfully, Vue allows us to customize it.
To customize the event
and ``prop, we add a model
property to our component and define the new values like this:
// ...
export default {
prop: ['hidden'],
model: {
prop: 'hidden',
event: 'blur'
}
methods: {
handleInput (value) {
this.$emit('blur', value)
}
}
}
// ...
This time, when you use the component like this:
<basic-input v-model="email" />
Vue will automatically convert it into:
<basic-input :hidden="email" @blur="e => email = e.target.value" />
With this in place, you can avoid conflicts when defining your component’s props and events.
v-model
on contenteditable
A content editable element is a div
or similar element that can be configured to work as an input.
We define content editable elements by adding the contenteditable
attribute to the element:
<div class="editor" contenteditable="contenteditable"></div>
You’ll use content editable elements for WYSIWYG editors as they are easier to work with and are supported by a large amount of browsers.
v-model
will work on content editable elements, but you need to explicitly use the content of the element, or the content will not be emitted.
To emit the content, you need to grab the innerText
or innerHTML
of the div
. So, our updateInput
method needs to look like this:
updateInput () {
this.$emit('input', this.$el.innerText)
}
You can also use the content of a ref
instead of the root element’s content.
With this in place, v-model
will work for content editable elements. You could also update this.content
in the updateInput
method.
Now that you have seen how to use v-model
with custom Vue components, you can go build or refactor your components that require the use of v-model
.
For further reading, consult the official documentation for v-model
or check out the Vue.js topic page for more exercises or projects.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
WARNING: out of date information. Please check the doumentation at
vuejs.org/guide/components/v-model.html#component-v-model
For using v-model on Components with the Composition API see: https://vuejs.org/guide/components/events.html#usage-with-v-model
isn’t it props instead of prop in the line: “prop: [‘value’],”