Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Understanding v-model and .sync for Two-Way Data Binding in Vue.js

Tech 3

In Vue.js, the v-model directive provides a convenient way to create two-way data bindings on form input, textarea, and select elements. It essentially combines data binding and event handling into a single directive.

How v-model Works

The v-model directive is syntactic sugar for binding a value to a component and listening for input events to update that value. For a standard input element, the following two examples are equivalent:

<!-- Using v-model -->
<input v-model="userInput">

<!-- Manual implementation -->
<input 
    :value="userInput"
    @input="userInput = $event.target.value">

Using v-model with Custom Components

When using v-model with custom components, Vue expects the component to have a prop named value and emit an event named input. Here's an example of a custom input component that works with v-model:

<div id="app">
    <custom-input v-model="counter"></custom-input>
    <p>Current value: {{counter}}</p>
</div>

<script>
Vue.component('custom-input', {
    template: `
    <div>
      <input
       ref="inputField"
       :value="value" 
       @input="$emit('input', $event.target.value)"
      >
    </div>
    `,
    props: ['value']
})
   
new Vue({
    el: '#app',
    data: {
        counter: 100,
    }
})
</script>

Customizing v-model for Special Input Types

For components like checkboxes or radio buttons that use the value attribute differently, you can customize the prop and event names using the model option:

Vue.component('toggle-switch', {
  model: {
    prop: 'isActive',
    event: 'toggle'
  },
  props: {
    isActive: Boolean
  },
  template: `
    <input
      type="checkbox"
      :checked="isActive"
      @change="$emit('toggle', $event.target.checked)"
    >
  `
})

The .sync Modifier

The .sync modifier provides another way to achieve two-way binding for props. It's particularly useful when you want to update a prop from within a child component. The .sync modifier is syntactic sugar that automatically handles the udpate event.

<!-- Using .sync -->
<child-component :visibility.sync="isVisible"></child-component>

<!-- Equivalent manual implementation -->
<child-component 
    :visibility="isVisible" 
    @update:visibility="val => isVisible = val">
</child-component>

To update a prop using .sync, emit an event with the pattern update:propName:

// Inside child component
this.$emit('update:visibility', false);

Practical Example of .sync

Here's a complete example demonstrating the use of .sync with a modal component:

<template>
    <div class="container">
        <modal-window :display.sync='showModal' 
                     style="padding: 30px 20px 30px 5px; border:1px solid #ddd; margin-bottom: 10px;">
        </modal-window>
        <button @click="toggleModal">Toggle Modal</button>
    </div>
</template>

<script>
import Vue from 'vue'

Vue.component('modal-window', {
    template: `<div v-if="display">
                  <p>Modal is currently {{display ? 'visible' : 'hidden'}}</p>
                  <button @click.stop="hideModal">Close Modal</button>
               </div>`,
    props: ['display'],
    methods: {
        hideModal() {
            this.$emit('update:display', false);
        }
    }
})

export default {
    data() {
        return {
            showModal: true,
        }
    },
    methods: {
        toggleModal() {
            this.showModal = !this.showModal;
        }
    }
}
</script>

Key Differences Between v-model and .sync

While both v-model and .sync enable two-way data binding, they have different use cases:

  • v-model is designed primarily for form inputs and follows the convention of using value prop and input event (configurable via model option).
  • .sync is more flexible and can be used with any prop name, following the update:propName event pattern.
  • v-model is typically used for a single primary value in a component, while .sync can be used for multiple props simultaneously.

When to Use Each Approach

Use v-model when:

  • Creating form-like components (inputs, selects, checkboxes)
  • You want the standard input/value pattern
  • Working with components that represent a single value

Use .sync when:

  • You need two-way binding for props that aren't form inputs
  • You want to update multiple props from a child component
  • You prefer explicit prop names rather than the generic value

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.