Skip to content
Advertisement

Setting a ‘default’ v-on event for a component within Vue

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

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement