I have a set of ‘text-input’ custom components which house some boilerplate markup and an ‘input’ element.
One way of getting the value of the ‘text-input’ in to it’s parent is to $emit an event when the value has changed.
I need to capture and handle the $emit with a v-on for every text-input component:
<text-input v-on:valueUpdated="storeInputValue" name='name'></text-input> <text-input v-on:valueUpdated="storeInputValue" name='email'></text-input> <text-input v-on:valueUpdated="storeInputValue" name='phone'></text-input>
I feel that this introduces too much repetition in the code, and I was wondering if there were a way to have the v-on listener on the component template itself:
<template v-on:valueUpdated="storeInputValue"> ... </template>
So that there is a ‘default’ v-on listener for this component, every time it is used.
Advertisement
Answer
You can use v-model
on custom components.
html
<div id="app> <text-input v-model="user.name" name="'name'"></text-input> <text-input v-model="user.email" name="'email'"></text-input> <text-input v-model="user.phone" name="'phone'"></text-input> <h4>{{user}}</h4> </div>
script
Vue.component('text-input', { name: 'text-input', template: ` <div> <label>{{name}}</label> <input type="text" :value="value" @input="storeInputValue($event.target.value)" /> </div> `, props: ['value', 'name'], methods: { storeInputValue(value){ this.$emit('input', value); } } }); //parent component new Vue({ el: '#app', data: { user: { name: '', email: '', phone: '' } } });
here is the example fiddle