vue.jsvuejs2vue-componentvue-flickity

Capture child components emitted action


I am attempting to react to a child components emitted action. The child emits an event/trigger/action called init. I attempt to register for that event in my parent components events map. But the callback never fires which makes me think I have incorrectly registered for the emitted action.

How can I react to a child's emitted an event/trigger/action?

<template>
    <flickity v-if="caseStudies && caseStudies.length > 0" id="case--studies_slider"ref="flickity" :options="flickityOptions">
        <div v-for="cs in caseStudies">
            {{cs.title}}
        </div>
    </flickity>
</template>

<script type="text/javascript">

import Flickity from 'vue-flickity' 

// NOTE computed properties (caseStudies) has been removed for brevity
// but I confirm that it does load with more than 1 element in the array

export default {

    components: {
        'Flickity': Flickity,  // Upon initialisation this should emit 'init'
    },

    data() {
        return {
            flickityOptions: {
              prevNextButtons: false,
            }
        }
    },

    events: {
      // This never fires!
      init() {
        console.log(foo)

        this.$refs.flickity.on('dragStart', (ev, pointer) => {
            $('#case--studies_slider').addClass('is-dragging')
        })

        this.$refs.flickity.on('dragEnd', (ev, pointer) => {
            $('#case--studies_slider').removeClass('is-dragging')
        })
      }
    },

    mounted() {

        // The below code causes a runtime error 'this.$refs.flickity' is undefined
        this.$refs.flickity.on('dragStart', (ev, pointer) => {
            $('#case--studies_slider').addClass('is-dragging')
        })

        this.$refs.flickity.on('dragEnd', (ev, pointer) => {
            $('#case--studies_slider').removeClass('is-dragging')
        })
    }
}
</script>

Solution

  • You'll need to bind the child event to the parent via v-on:

    <template>
        <flickity v-if="caseStudies && caseStudies.length > 0" id="case-- 
        studies_slider"ref="flickity" :options="flickityOptions"
        v-on:init="doSomething()">
            <div v-for="cs in caseStudies">
                {{cs.title}}
            </div>
        </flickity>
    </template>
    
    <script type="text/javascript">
    
    import Flickity from 'vue-flickity' 
    
    export default {
    
        components: {
            'Flickity': Flickity,
        },
    
        data() {
            return {
                flickityOptions: {
                  prevNextButtons: false,
                }
            }
        },
        methods: {
            doSomething() {
                // this will be called when the 'init' event is triggered
            }
        },
    }
    </script>