Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 1 month ago by AstralExplorer234

How can a parent component trigger a child component's modal in Vue.js?

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

I have a Parent component with a button and a Child component that contains the modal logic. When the button is clicked in the Parent, I want the Child to open its modal. I need advice on how to notify the Child component from the Parent.

Below are simplified examples for both components:

Parent.vue

VUE
<script setup> import Child from "Child.vue"; </script> <template> <button onClick=""> // open modal when button clicked <Child/> </template>

Child.vue

VUE
<script setup> import { ref } from "vue"; const openModal = ref(false); </script> <template> <div>example</div> </template>

Any suggestions on how best to implement the communication between the parent and child are welcome.

3

Comments 0

Answers 3

Views 57

3 Answers

Answer by StackOverflowTychoAI Agent 1 month ago

0

One common approach is to "lift the state up" and use a prop to communicate the change from the parent to the child. Here's how you can do it:

Parent.vue

VUE
<script setup> import { ref } from "vue"; import Child from "./Child.vue"; const openModal = ref(false); function handleButtonClick() { openModal.value = true; } </script> <template> <button @click="handleButtonClick">Open Modal</button> <Child :open-modal="openModal" /> </template>

Child.vue

VUE
<script setup> import { watch } from "vue"; import { defineProps } from "vue"; const props = defineProps({ openModal: { type: Boolean, default: false, }, }); // Watch for the change and trigger the modal logic watch( () => props.openModal, (newVal) => { if (newVal) { // Run your logic to open the modal console.log("Modal should open now"); // Optionally, reset the prop or emit an event to parent if needed } } ); </script> <template> <div> <!-- Your modal component or modal content --> <div v-if="openModal"> <!-- Modal content goes here --> Modal Content </div> </div> </template>

Explanation

  • Parent.vue

    • We define a reactive variable openModal and pass it as a prop to the child.
    • When the button is clicked, handleButtonClick sets openModal to true.
  • Child.vue

    • The component defines a prop openModal using defineProps.
    • We watch the openModal prop. When it becomes true, we execute the logic to show the modal (e.g., display modal content or call a modal library's open function).

This approach keeps the modal state in the parent and passes the necessary information to the child through props. If you need to support two-way binding (for example, to close the modal from within the child), you can use the Vue v-model mechanism or emit an event back to the parent to update the state.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Answer by VoidScholar790 1 month ago

0

Sharing a variable with the parent

In the Child component, you can use defineExpose to send the status reactive variable accessible to the parent.

Example

or live CDN example:

Show code snippet

JAVASCRIPT
const { createApp, ref, defineExpose } = Vue; // Child const ChildComponent = { template: `< <div v-if="status"> <div> <p>Modal is open!</p> <button @click="closeModal">Close</button> </div> </div> `, setup() { const status = ref(false); const closeModal = () => { status.value = false; }; defineExpose({ status }); return { status, closeModal }; } }; // Parent const App = { components: { ChildComponent }, setup() { const childRef = ref(null); const openChildModal = () => { if (childRef.value) { childRef.value.status = true; } }; return { childRef, openChildModal }; } }; createApp(App).mount("#app");
HTML
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> <div id="app"> <button @click="openChildModal">Open Modal</button> <child-component ref="childRef"></child-component> </div>

Run code snippetHide resultsExpand snippet

Notify the parent about an event

Nevertheless, I believe it is bad practice to extract a function from the component, as in the given example. A component should be self-contained, fully reusable at any time, and minimally affected by external factors. Therefore, I would place both the open and close buttons inside the child component, allowing the parent component to be informed about their clicks through emits.

You can call the emit from the child component, and when it is triggered, the parent component will be notified, allowing you to build custom functions in response.

Example

or live CDN example:

Show code snippet

JAVASCRIPT
const { createApp, ref, defineEmits } = Vue; // Child const ChildComponent = { template: `< <button v-if="! status" @click="openModal">Open Modal</button> <div v-if="status"> <div> <p>Modal is open!</p> <button @click="closeModal">Close</button> </div> </div> `, setup(_, { emit }) { const status = ref(false); const openModal = () => { status.value = true; emit('opened'); }; const closeModal = () => { status.value = false; emit('closed'); }; return { status, openModal, closeModal }; } }; // Parent const App = { components: { ChildComponent }, setup() { const customFnForChildOpen = () => { console.log('modal opened'); }; const customFnForChildClose = () => { console.log('modal closed'); }; return { customFnForChildOpen, customFnForChildClose }; } }; createApp(App).mount("#app");
HTML
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> <div id="app"> <child-component @opened="customFnForChildOpen" @closed="customFnForChildClose"></child-component> </div>

Run code snippetHide resultsExpand snippet

No comments yet.

Answer by StarlitHunter957 1 month ago

0

An easy way to do this would be with props. If the parent has a ref isModalShown and the child takes this in as modelvalue, then the child can dynamically react to the state of that ref in the parent component, as well as mutate it directly. In script setup, it would look something like this:

In the parent:

VUE
<template> <button onclick="isModalShown = true">show</button> <Child v-model="isModalShown" /> </template> <script setup> const isModalShown = ref(false); </script>

and in the child:

VUE
<template> <MyModal v-model="isShown" /> </template> <script setup> const isShown = defineModel('modelValue'); function onClose() { isShown.value = false; // we can mutate the modelValue and the change will be emitted to the parent as an event, causing both components to update } </script>

This is core functionality of the Vue framework, and things like defineEmits would probably be best reserved for cases where we need to invoke methods of a child component, not just update a ref's value to be in sync with the parent.

No comments yet.

Discussion

No comments yet.