3

I have a component TopBar.vue and I'm trying to open a modal (a child component Feedback.vue).

How do I bind the showFeedbackModal property between both components?

I want to make it so that when you click the <a> tag with @click="showFeedbackModal = true the value true gets passed to the <feedback> component and the modal is shown.

TopBar.vue (Main)

<template>
    <div>
        <section class="top-bar level">
            <div class="level-left">
                ...

                <ul class="level-item">
                    <li><a @click="showFeedbackModal = true"><i class="fa fa-envelope-open-o" aria-hidden="true"></i> Beta Feedback</a></li>
                </ul>
            </div>
            ...           
        </section> 

        <feedback :showFeedbackModal="showFeedbackModal"></feedback>            
    </div>
</template>

<script>
    export default {
        data() {
            return {
                showFeedbackModal: false
            }
        }
    }
</script>

Feedback.vue (modal)

<template>
    <div>
        <div v-if="showModal" class="modal is-active">
            <div class="modal-background" @click="showModal = false"></div>
            <div class="modal-content">
                <div class="box">
                    This is the feedback content
                </div>
            </div>
            <button class="modal-close" @click="showModal = false"></button>
        </div>
    </div>
</template>

<script>
    export default {        
        props: ['showFeedbackModal'],

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

        beforeMount() {
            this.showModal = this.showFeedbackModal;
        }
    }
</script>

1 Answer 1

3

You are setting your showModal property in the Feedback component's mounted hook. This means that when the component is mounted to the DOM, the value of showModal will be set to whatever showFeedbackModal is initially but then won't change if the value of showFeedbackModal ever changes.

You should just make showModal a prop in your Feedback component:

export default {        
    props: ['showModal'],
}

And then, in your TopBar component, you just need to pass the showFeedbackModal variable as the value for the showModal property:

<feedback :showModal="showFeedbackModal"></feedback> 

If you want the Feedback modal component to be able to affect its parent component's showFeedbackModal variable, you can emit a custom event in the Feedback component:

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

And then update the value of showFeedbackModal in the handler for that event:

<feedback 
  :showModal="showFeedbackModal" 
  @close="showFeedbackModal = false"
></feedback> 
Sign up to request clarification or add additional context in comments.

6 Comments

Agh. So close. This makes sense. Let me try it out.
So the modal will appear. But I get an error when I try closing (by clicking close button or modal background): Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "showModal"
You should emit an event and let the parent component handle the data manipulation. See my edit.
Awesome. Works - thanks for your help! I'm slowly coming to terms. ;)
Nope. You can't change the value of a property passed into a component.
|

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.