Currently in the process of revamping our components that are originally built using the Options API. A key point for refactoring from a code-cut perspective is how we handle our multiple modals, each with their own open/close and boolean logic scattered throughout.
The challenge I'm facing is figuring out how to implement a composable function that can handle more than one instance of a modal.
For example, consider this simple scenario:
Modal.vue
<template>
<div v-if="isOpen" @click="$emit('closeModal')">
<slot></slot>
</div>
</template>
const props = defineProps<{ isOpen: false }>();
useModal.ts
export default const useModal = () => {
const isModalOpen = ref(false);
const toggleModal = () => isModalOpen.value = !isModalOpen.value;
return { isModalOpen, toggleModal }
}
To use this in a component, you would typically do something like this
Component.vue
<template>
<button @click="toggleModal">Open Modal<button>
<Modal :is-open="isModalOpen" @close-modal="toggleModal">Modal Content</Modal>
</template>
import useModal from "useModal";
const { isModalOpen, toggleModal } = useModal();
This approach works well when there's only one Modal present on the page. But how can we scale this to work with multiple Modals seamlessly? How can we avoid duplicating the content of the useModal
composition for each individual Modal?
Ideally, we'd want to achieve something like this
<template>
<button @click="toggleOne">Open 1</button>
<button @click="toggleTwo">Open 2</button>
<Modal :is-open="isOneOpen" @close-modal="toggleOne">Modal 1</Modal>
<Modal :is-open="isTwoOpen" @close-modal="toggleTwo">Modal 2</Modal>
</template>
import useModal from "useModal";
const { isOneOpen, toggleOne } = useModal();
const { isTwoOpen, toggleTwo } = useModal();
However, this approach doesn't work as intended. Is there a way for me to achieve my goal here, or am I missing a fundamental concept regarding the usage of composables?
I've experimented with variations like the following
const { isModalOpen as isOneOpen } = useModal();
const isOneOpen = useModal().isModalOpen;
const isOneOpen = { ...useModal().isModalOpen; };
Unfortunately, none of these attempts yielded the desired outcome.