Search code examples
javascriptvue.jseventscustom-component

Events registered in reusable vue components not working


On the site I'm working on, I repeatedly use components such as buttons and dropdowns. Because I use them so often I've decided to create a custom component for particular features so that I don't have to redeclare styling. One such component is: BlueButton.vue

<template>
    <v-btn dark color="blue" class="blue-btn">
        <slot>
            <!--  -->
        </slot>
    </v-btn>
</template>

I'm then trying to use this component inside a form component called TheForm.vue:

<template>
    <blue-button @click="showTheDialog = false" v-if="thebutton(btn)">Cancel</blue-button>
</template>
<script>
import BlueButton from '../components/BlueButton'

export default {

    props: {
        //
    },

    components: {
        'blue-button' : BlueButton
    },
</script>

However, although the button inside of TheForm.vue is styled correctly, events such as @click and v-if aren't registering (i.e. I can click the button but it won't do anything - It won't even show an error).

How can I fix this so that props and events work?


Solution

  • Events won't automatically propagate up when you wrap a component.

    You'd either need to pass them on individually, something like this:

    <v-btn dark color="blue" class="blue-btn" @click="$emit('click', $event)">
    

    Or you can pass on all events like this:

    <v-btn dark color="blue" class="blue-btn" v-on="$listeners">
    

    See:

    https://v2.vuejs.org/v2/api/#vm-listeners

    The v-if directive should be working correctly. You don't need to do anything special to get that to work.

    If you need to pass props it's much the same as with events. You either need to pass them on individually or all together. To pass them all together it'd be:

    <v-btn dark color="blue" class="blue-btn" v-bind="$attrs">
    

    Note that $attrs will only contain attributes that are not defined as props, so for any that you do define as props you'll need to pass those separately.

    See:

    https://v2.vuejs.org/v2/api/#vm-attrs