Multiple composable instances in single script tag in Vue 3
P粉763748806
P粉763748806 2024-01-17 09:49:26
0
1
503

I am currently working on a rewrite of a component we wrote using the Options API. From a code shearing perspective, an interesting rewrite point is that many of our modal boxes have their own close/open and boolean logic attached to them everywhere they appear.

My problem is that I'm having trouble figuring out how to make one composable function work for multiple modal instances.

Take this very simple example:

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 }
}

Then to use it in a component, you can do this:

Component.vue

<template>
  <button @click="toggleModal">打开模态框<button>
  <Modal :is-open="isModalOpen" @close-modal="toggleModal">模态框内容</Modal>
</template>
import useModal from "useModal";

const { isModalOpen, toggleModal } = useModal();

This is perfectly fine when there is only one modal box on the page, but how do you make it work for any number of modal boxes? Obviously I still need to define variable names to keep track of which modal is toggled/opened, but how do I achieve this without re-creating the useModal combined content for each modal?

Ideally I would like to do something similar to this

<template>
  <button @click="toggleOne">打开1</button>
  <button @click="toggleTwo">打开2</button>

  <Modal :is-open="isOneOpen" @close-modal="toggleOne">模态框1</Modal>
  <Modal :is-open="isTwoOpen" @close-modal="toggleTwo">模态框2</Modal>
</template>
import useModal from "useModal";

const { isOneOpen, toggleOne } = useModal();
const { isTwoOpen, toggleTwo } = useModal();

But this doesn't work (obviously). Is there a way to achieve my goal here, or do I have a fundamental misunderstanding of how/when to use combined functions?

I tried some variations, like this

const { isModalOpen as isOneOpen } = useModal();

const isOneOpen = useModal().isModalOpen;

const isOneOpen = { ...useModal().isModalOpen; };

But none of these work for me.

P粉763748806
P粉763748806

reply all(1)
P粉680487967

You can reassign the name of the return value of a composable function during object destructuring as follows:

const { isModalOpen: modalOne, toggleModal: toggleModalOne } = useModal();

This is enough to distinguish the state of the modal box to be tracked.

Working example here: https://codesandbox.io/s/vue-3-composition-destructuring-fts2x9

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template