Vue.js

Custom Components with v-model

Introduction#

Often times we have to create some components which perform some actions/operations on data and we require that in the parent component. Most of the times vuex would be a better solution, but in cases where the child component’s behavior has nothing to do with application state, for instance: A range-slider, date/time picker, file reader

Having individual stores for each component each time they get used gets complicated.

Remarks#

To have v-model on a component you need to fulfil two conditions.

  1. It should have a prop named ‘value’
  2. It should emit an input event with the value expected by the parent components.

<component v-model='something'></component>

is just syntactic sugar for

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

v-model on a counter component

Here counter is a child component accessed by demo which is a parent component using v-model.

// child component
Vue.component('counter', {
  template: `<div><button @click='add'>+1</button>
  <button @click='sub'>-1</button>
  <div>this is inside the child component: {{ result }}</div></div>`,
  data () {
    return {
      result: 0
    }
  },
  props: ['value'],
  methods: {
    emitResult () {
      this.$emit('input', this.result)
    },
    add () {
      this.result += 1
      this.emitResult()
    },
    sub () {
      this.result -= 1
      this.emitResult()
    }
  }  
})

This child component will be emitting result each time sub() or add() methods are called.


// parent component
new Vue({
  el: '#demo',
  data () {
    return {
      resultFromChild: null
    }
  }
})

// parent template
<div id='demo'>
  <counter v-model='resultFromChild'></counter>
  This is in parent component {{ resultFromChild }}
</div>

Since v-model is present on the child component, a prop with name value was sent at the same time, there is an input event on the counter which will in turn provide the value from the child component.


This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow