368

I'm learning Vue with an online course and the instructor gave me an exercise to make an input text with a default value.

I completed it using v-model but, the instructor chose v-bind:value, and I don't understand why.

Can someone give me a simple explanation about the difference between these two and when it's better use each one?

Gustavo Dias
  • 3,811
  • 3
  • 11
  • 6
  • 11
    `v-model` is used mainly for input and form bidning, so use it when you dealing with various input types.`v-bind` directive allow you to produce some dynamic value by typing some JS expression that in most cases depends on the data from data model - so think about v-bind as directive that you should use when you want deal with some dynamic things. – Belmin Bedak Feb 15 '17 at 22:15
  • 6
    In some case you can use each of them. Sometimes not, for example: `
    ` - you can't bind html attribute using model, you should use `v-bind` directive. For form's elements you will want to use `v-model` directive - "it automatically picks the correct way to update the element based on the input type."
    – Alexander Feb 27 '17 at 15:48
  • 1
    @Alexander The phrase "bind HTML attribute" helped me think about this better. It would be good to see you weigh in on this with a more complete answer about what's actually happening with these two constructs. – Tom Russell Oct 08 '18 at 06:58
  • @Alexander Esp in the context of component `data` and `props`... – Tom Russell Oct 08 '18 at 07:08

5 Answers5

671

From here - Remember:

<input v-model="something">

is essentially the same as:

<input
   v-bind:value="something"
   v-on:input="something = $event.target.value"
>

or (shorthand syntax):

<input
   :value="something"
   @input="something = $event.target.value"
>

So v-model is a two-way binding for form inputs. It combines v-bind, which brings a js value into the markup and v-on:input to update the js value. The js value must be present in your data, or in an inject.

Use v-model when you can. Use v-bind/v-on when you must :-) I hope your answer was accepted.

v-model works with all the basic HTML input types (text, textarea, number, radio, checkbox, select). You can use v-model with input type=date if your model stores dates as ISO strings (yyyy-mm-dd). If you want to use date objects in your model (a good idea as soon as you're going to manipulate or format them), do this.

v-model has some extra smarts that it's good to be aware of. If you're using an IME ( lots of mobile keyboards, or Chinese/Japanese/Korean ), v-model will not update until a word is complete (a space is entered or the user leaves the field). v-input will fire much more frequently.

v-model also has modifiers .lazy, .trim, .number, covered in the doc.

tony19
  • 125,647
  • 18
  • 229
  • 307
bbsimonbb
  • 27,056
  • 15
  • 80
  • 110
  • 66
    'Use v-model when you can. Use v-bind/v-on when you must'. Great summary! Thank you very much! – 尤川豪 Dec 04 '17 at 05:29
  • What's the difference between `v-model` and `v-bind:xxx.sync`? – El Mac Jan 04 '19 at 19:24
  • 3
    @ElMac v-model is a two-way binding between a Vue component and a javascript model. The source (the model side of the binding) is declared in the data of the Vue component. Like this, Vue lets you extract state from your components, then modify this state directly from the component. It's a simple pattern for state management that is a hallmark of Vue (difficult/hidden/impossible/discouraged in Angular and React). v-bind:xxx.sync is a two-way binding between a Vue component and its parent]. The state stays encapsulated. It 'belongs' to the parent. This is not necessarily better! – bbsimonbb Jan 11 '19 at 11:02
  • "is essentially the same as" - WRONG. When you use `v-model` it "touches" the object and all inputs will be redrawn, even the ones that use `v-bind`. When you assign `something = $event.target.value` - it won't redraw – Alex from Jitbit Nov 20 '20 at 17:14
  • @Alex how do you know this? What practical difference does it make? When you say "all inputs", you use v-model on one input at a time. – bbsimonbb Nov 20 '20 at 17:38
  • @bbsimonbb I bumped into this many times. To emulate v-model behavior in full it should be `Vue.set(obj, 'something', $event.target.value)` so you don't just update a property, but trigger vue's reactivity too. – Alex from Jitbit Nov 20 '20 at 18:52
  • Vue's reactivity is triggered with `=`. `Vue.set()` is useful in specific cases like arrays, but so long as you assign properties, and take care to not overwrite the root of a watched object, `=`works just fine. – bbsimonbb Dec 08 '20 at 13:28
95

In simple words:

v-model: two way bindings

if you change input value, the bound data will be changed and vice versa.

v-bind:value one way binding

You can change input value by changing bound data but you can't change bound data by changing input value through the element_.

Check out this simple example: https://jsfiddle.net/gs0kphvc/

Madmadi
  • 2,064
  • 1
  • 14
  • 17
  • 2
    ' if you change input value, the bound data will be changed and vice versa. ' - can't understand the 'vice versa' part even from the fiddle example. can you explain it ? – Istiaque Ahmed Jan 01 '20 at 21:20
  • if you change input value through the element, the bound data will be changed and also if you change bound data through for example Vue APIs your input element value would change. – Madmadi Jan 05 '20 at 18:35
  • how to change bound data through Vue API ? – Istiaque Ahmed Jan 05 '20 at 19:42
  • In fiddle example, say we have a method that changes data_source like this `this.data_source = 'Some new value'` – Madmadi Jan 06 '20 at 02:47
  • by `data_source`, you mean the HTML injected in DOM from `input`, right ? – Istiaque Ahmed Jan 06 '20 at 07:37
  • v-bind:value and v-model can't be used on same input element. – Muhammad Aug 10 '20 at 18:14
  • @Istiaque Ahmed, when you change the data_source here, in the Vue instance - data: { data_source: 'dsadsadasdsa', }, this will be applied to the v-model="data_source", and vice versa, because data_source in the template is bound to the data_source in the Vue instance via v-model. This is the two-way data binding in action. See this fiddle and try it. https://jsfiddle.net/opa4q7x1/ – Petya Naumova Feb 22 '21 at 18:32
9

v-model is for two way bindings means: if you change input value, the bound data will be changed and vice versa. But v-bind:value is called one way binding that means: you can change input value by changing bound data but you can't change bound data by changing input value through the element.

v-model is intended to be used with form elements. It allows you to tie the form element (e.g. a text input) with the data object in your Vue instance.

Example: https://jsfiddle.net/jamesbrndwgn/j2yb9zt1/1/

v-bind is intended to be used with components to create custom props. This allows you to pass data to a component. As the prop is reactive, if the data that’s passed to the component changes then the component will reflect this change

Example: https://jsfiddle.net/jamesbrndwgn/ws5kad1c/3/

sda87
  • 372
  • 3
  • 10
7

v-model
it is two way data binding, it is used to bind html input element when you change input value then bounded data will be change.

v-model is used only for HTML input elements

ex: <input type="text" v-model="name" > 

v-bind
it is one way data binding,means you can only bind data to input element but can't change bounded data changing input element. v-bind is used to bind html attribute
ex:
<input type="text" v-bind:class="abc" v-bind:value="">

<a v-bind:href="home/abc" > click me </a>
2

There are cases where you don't want to use v-model. If you have two inputs, and each depend on each other, you might have circular referential issues. Common use cases is if you're building an accounting calculator.

In these cases, it's not a good idea to use either watchers or computed properties.

Instead, take your v-model and split it as above answer indicates

<input
   :value="something"
   @input="something = $event.target.value"
>

In practice, if you are decoupling your logic this way, you'll probably be calling a method.

This is what it would look like in a real world scenario:

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input :value="extendedCost" @input="_onInputExtendedCost" />
  <p> {{ extendedCost }}
</div>

<script>
  var app = new Vue({
    el: "#app",
    data: function(){
      return {
        extendedCost: 0,
      }
    },
    methods: {
      _onInputExtendedCost: function($event) {
        this.extendedCost = parseInt($event.target.value);
        // Go update other inputs here
    }
  }
  });
</script>
Vincent Tang
  • 3,758
  • 6
  • 45
  • 63