What is the difference between v-model and .sync when used on a custom component

14,494

Solution 1

For Vue.js 2 both pretty much do the same thing - enable two-way binding, although .sync is more versatile. It was added after v-model was added for components. .sync allows to use v-model logic for more than one prop. Let's compare:

<comp :value.sync="username" :age.sync="userAge" />

expands to:

<comp :value="username" :age="userAge" @update:name="val => userName = val" @update:age="val => userAge = val" />
<comp v-model="userName" />

expands to:

<comp :value="username" @input="val => username = val" />

The differences as we can see are:

  • the default prop name v-model always binds to property called value

  • .sync allows you to use multiple props

  • the event name emitted from component (@update for .sync and @input for v-model)

One very interesting feature of .sync is its special handling of objects. The .sync modifier when used on an object will set multiple props at once (more here)

Which one to use? It is a standard pattern to use property value as the key value carrier for a component. In this situation if you have value property and want to enable 2-way binding for it then use v-model. In all other cases use .sync

Solution 2

There isn't much difference, so much so that there is a plan to potentially merge them in Vue 3:

https://github.com/vuejs/rfcs/pull/8

In cases where a component has a natural candidate for two-way binding you'd use v-model. So text inputs, checkboxes, etc. would all use v-model. Similarly it might make sense in the context of a component with a concept of selection. You could use sync instead but it isn't typically what other developers would be expecting.

In Vue 2 you can only have a single prop/event wired up to v-model. If you want two-way binding for multiple props/events then you'd have to use sync.

Vuetify contains several examples of components that use both v-model and sync. For example, v-autocomplete:

https://vuetifyjs.com/en/components/autocompletes

This uses v-model for the selected value but it also uses sync for error and search-input.

Share:
14,494
Peter Petrus
Author by

Peter Petrus

Updated on June 03, 2022

Comments

  • Peter Petrus
    Peter Petrus almost 2 years

    I don't understand the difference between v-model and .sync used on a component.

    <my-component v-model="myVar">
    

    V-model is a shorthand for binding a variable (myVar) to the component property 'value' and listening to the 'input' event emitted from the component to update the variable 'myVar'.

    <my-component v-bind:prop1.sync="myVar">
    

    .sync is a shorthand for binding a variable (myVar) to a component property ('prop1' in this case) and listening to the 'update:prop1' event emitted from the component to update the variable 'myVar'.

    I know that by default v-model only works with the 'value' property and the 'input' event but even that can be customized using the 'model' option in the component.

    Would be nice if anybody could explain the difference to me or when to use what.

    Here is an example where I used the same component in three different ways: 1) manual binding + event listening 2) .sync 3) v-model

  • Sanil Khurana
    Sanil Khurana almost 4 years
    Wanted to add a point that you missed. We don't necessarily need to use the 'value' prop and the 'input' event. We can modify it - digitalocean.com/community/tutorials/…
  • Max Coplan
    Max Coplan over 3 years
    Do you think it makes sense for someone developing components for other develops to support both the v-model and .sync apis for their 'single editable prop' components? i.e. emit both input and update:value? I worry about emitting too many events, but also figure that won't be an issue
  • Melroy van den Berg
    Melroy van den Berg over 2 years
    It says deprecated for me, see also: eslint.vuejs.org/rules/no-deprecated-v-bind-sync.html
  • rubebop
    rubebop about 2 years
    @husayt, I think there´s a typo in the 2nd line of code: @update:value="val => userName = val". In other words, the property that, when changed, triggers the update is value and not name.