0

I'm using single file components triggered from vue-router. I have a components/Header.vue which uses a child modals/HelpModal.vue which in turn has a child components/Modal.vue.

I'm trying to pass around events in order to keep Modal.vue re-usable, but I can't seem to access this.show from within an event in HelpModal.vue

Modal.vue

<template>
    <div class="modal">
        <button class="modal__close" @click="$emit('close')">
        </button>

        <slot></slot>
    </div>
</template>

HelpModal.vue

<template>
    <modal v-if="show" @close="closeModal">...help modal content...</modal>
</template>

<script>
import Modal from 'components/Modal.vue'
import bus from 'eventBus'

export default {

    components: {
        Modal
    },

    data: () => {
        return {
            show: false
        }
    },

    methods: {
        closeModal: () => {
            this.show = false
        }
    },

    mounted: () => {
        bus.$on('showHelpModal', () => {
            console.log('show modal!', this.show); // undefined
            this.show = true
        })
    }
}

Header.vue

<template>
    <header>
        <button @click="showHelpModal">Show help</button>
        <help-modal></help-modal>
    </header>
</template>

<script>
    import HelpModal from 'views/modals/HelpModal.vue'
    import bus from 'eventBus'

    export default {

        components: {
            HelpModal
        },

        methods: {
            showHelpModal: () => {
                bus.$emit('showHelpModal')
            }
        }
    }
</script>

I may be going about this all totally wrong, but it's the only way I can see it working to have a link in the header that triggers the help modal to open

2 Answers 2

5

Don't use arrow functions to define your methods. At execution this will be wrong, because arrow functions preserve the this (also called context) from the time of their definition. Methods are defined as part of the component definition process, so the component is not the context when the method is being defined.

An ordinary function definition will determine context based on how it is called, so component.method() will have component as its context, which is what you want.

If your method doesn't reference this, you can use arrow functions, but I recommend against it, because there will come times that you update the definition, use this, and it will bite you.

Sign up to request clarification or add additional context in comments.

Comments

1

try this:

data() {
    return {
        show: false
    }
},

This is how I use my data for my components.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.