Module: Vue Directives

v-model

Vue Directives: v-model

The v-model directive is a powerful tool in Vue.js for creating two-way data bindings. It simplifies handling form input and keeping your data synchronized with the user interface.

What does v-model do?

Essentially, v-model is syntactic sugar for a combination of:

  • :value attribute binding (one-way data binding from the component's data to the input)
  • @input event listener (listening for user input changes and updating the component's data)

Basic Usage

The most common use case is with <input> elements:

<template>
  <div>
    <input type="text" v-model="message">
    <p>Message: {{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    }
  }
}
</script>

In this example, any changes made in the input field will automatically update the message data property, and vice-versa. The paragraph will dynamically display the current value of message.

v-model with Different Input Types

v-model behaves slightly differently depending on the input type:

  • Text & Textarea: Two-way binding to the value property.

    <input type="text" v-model="name">
    <textarea v-model="description"></textarea>
    
  • Checkbox: Two-way binding to the checked property. The value bound to v-model will be a boolean (true if checked, false if not).

    <input type="checkbox" id="agree" v-model="agreed">
    <label for="agree">I agree</label>
    
  • Radio: Two-way binding to the value property. Multiple radio buttons with the same v-model will share the same bound value. The selected radio button's value will be assigned to the v-model variable.

    <input type="radio" id="one" value="one" v-model="picked">
    <label for="one">One</label>
    <input type="radio" id="two" value="two" v-model="picked">
    <label for="two">Two</label>
    
  • Select: Two-way binding to the value property.

    • Single Select: The value bound to v-model will be the selected option's value.

      <select v-model="selected">
        <option value="a">A</option>
        <option value="b">B</option>
      </select>
      
    • Multiple Select: The value bound to v-model will be an array of the selected option values.

      <select v-model="selectedOptions" multiple>
        <option value="a">A</option>
        <option value="b">B</option>
        <option value="c">C</option>
      </select>
      

Modifiers

v-model supports modifiers to customize its behavior:

  • .lazy: Updates the data only after the input loses focus (on blur event instead of input). Useful for performance optimization when dealing with expensive operations.

    <input type="text" v-model.lazy="message">
    
  • .number: Automatically converts the input value to a number. Useful for numeric inputs.

    <input type="number" v-model.number="age">
    
  • .trim: Automatically trims whitespace from the input value.

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

Custom Input Components

v-model can also be used with custom components. The component needs to:

  1. Accept a value prop.
  2. Emit an input event when the value changes.
// CustomInput.vue
<template>
  <input :value="value" @input="$emit('input', $event.target.value)">
</template>

<script>
export default {
  props: {
    value: String
  }
}
</script>
// Parent Component
<template>
  <div>
    <CustomInput v-model="myValue" />
    <p>Value: {{ myValue }}</p>
  </div>
</template>

<script>
import CustomInput from './CustomInput.vue';

export default {
  components: {
    CustomInput
  },
  data() {
    return {
      myValue: ''
    }
  }
}
</script>

Important Considerations

  • v-model only works with form elements and custom components that follow the specified prop/event convention.
  • Be mindful of data types when using .number. If the input is not a valid number, it will be converted to NaN.
  • For complex form validation, consider using a dedicated form validation library.