I need an asymmetrical communicatione among SFCs

Hi guys,
I created a SFC that acts as a generic modal dialog.
The dialog exposes a prop called visible so that the caller, that is usually another SFC, can write something like this (composition API):

<script setup>
    const dialogShow=ref(false);
    ...
</script>

<template>
    <common-dialog :visible="dialogShow" />
</template>

Naturally every time the caller needs the dialog shows, it can change the prop value this way:

dialogShow.value=true;

The problem pops up when the dialog needs to close itself.
Since it can’t modify the value of its own property, it needs to delegate the task to the caller.
In Vue props go down and events go up so that I implemented an event that the dialog raises when it needs to be closed, for example when the user clicks the Ok button or the little cross button in the upper right side.
So my dialog is supplied with an event like this one:

const emit = defineEmits(['pleaseCallerCloseMe']);

function closeDialog(){
    emit('pleaseCallerCloseMe');
}

Naturally when the caller receives the event it changes the prop value and the dialog closes.

dialogShow.value=false;

Everything works well but I feel that’s something evil in this kind of architecture.

A dialog knows when it needs to be closed and it should be able to do that without collaboration.
If the caller needs to be notified about the closing I can create an event (the usual onClosing). But the event implementation should be optional because usually the caller doesn’t need to know anything about the dialog.
Is there a trivial solution to solve this kind of problem?

Thanks.

You could make a custom v-model for the visible property, that way both the the modal and the modal’s parent can edit it. Here are the docs on how to do that. But basically you would do this on your parent <common-dialog v-model:visible="dialogShow" />, and then on your modal you would define an emit called update:visible. Now you can close the modal from the modal using emit('update:visible', false). Let me know if you have any questions or if it doesn’t work, happy to help.

1 Like