Открытие диалогового окна Healdess UI (модальное) через другое диалоговое окно (модальное) автоматически закрывает предыдущее диалоговое окно (модальное)? (Добавлена ​​ссылка на воспроизведение CodeSandBox)

Я использую компонент HeadlessUI/Vue в своем приложении Nuxt 3 для создания диалоговых окон/модальных окон. Я использую последнюю версию "@headlessui/vue": "^1.7.22" и разрабатываю последнюю версию браузера Chrome.

Я создаю DialogPanel1.vue, используя headlessui/vue. У меня есть кнопка DialogPanel1.vue, при нажатии на нее я открываю DialogPanel2.vue, но внутри DialogPanel2.vue, когда я нажимаю где-нибудь, она автоматически закрывает DialogPanel1.vue, которая находится за DialogPanel2.vue.

Репозиторий с минимальным воспроизведением в CodeSandBox

Почему он закрывается DialogPanel1 автоматически? Я хочу, чтобы DialogPanel1 закрывался только тогда, когда я нажимаю кнопку закрытия в DialogPanel1.vue, а не при каждом нажатии DialogPanel2. Я попробовал добавить @click.stop или @mousedown.stop, чтобы предотвратить распространение события, но это все равно не работает. Может кто-нибудь, пожалуйста, дайте мне знать о проблеме?

Ниже приведен мой полный код /pages/index.vue:

<template>
  <DialogPanel1 />
</template>
  
<script setup>
</script>

Ниже приведены мои компоненты /component/DialogPanel1.vue:

<template>
  <div class = "mb-2">
    <button
      type = "button"
      @click = "openModal1"
      class = "flex secondary-button text-secondary dark:bg-transparent dark:hover:text-secondary dark:hover:bg-slate-700 mx-auto justify-center items-center rounded border focus:ring-0 focus:outline-none font-medium px-5 py-2.5 text-center min-w-[8rem] sm:min-w-[10rem] lg:min-w-[12rem]"
    >
      <span class = "pr-1"> Open Modal-1 </span>
    </button>
  </div>

  <TransitionRoot appear :show = "modal1" as = "template">
    <Dialog as = "div" @close = "closeModal" class = "relative z-30">
      <div class = "fixed inset-0 overflow-y-auto">
        <div
          class = "flex min-h-full items-center justify-center p-4 text-center"
        >
          <DialogPanel
            class = "dark:bg-slate-800 w-full transform overflow-auto rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all z-20"
          >
            THIS IS MODAL-1
            <button
              class = "flex secondary-button text-secondary dark:bg-transparent dark:hover:text-secondary dark:hover:bg-slate-700 mx-auto justify-center items-center rounded border focus:ring-0 focus:outline-none font-medium px-5 py-2.5 text-center min-w-[8rem] sm:min-w-[10rem] lg:min-w-[12rem]"
              @click = "openModal2"
            >
              MODAL-2
            </button>
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>

  <DialogPanel2 :modal2 = "modal2" @closeModal = "hideModal2" />
</template>
    
<script setup>
import { TransitionRoot, Dialog, DialogPanel } from "@headlessui/vue";

const modal1 = ref(false);
const modal2 = ref(false);

//Function to open Modal-1
const openModal1 = () => {
  console.info("Opening Modal-1");
  modal1.value = true;
};

//Close the modal on click of the button
const closeModal = () => {
  console.info("CLOSE MODAL-1");
  modal1.value = false;
};

//Function to open Modal-2
const openModal2 = () => {
  console.info("Open MODAL-2");
  modal2.value = true;
};

const hideModal2 = () => {
  console.info("Closing MODAL-2");
  modal2.value = false;
};
</script>

Ниже мой /components/DialogPanel2.vue:

<template>
  <TransitionRoot
    appear
    :show = "modal2"
    as = "template"
    @close = "closeModal"
    @click.native.stop.prevent
  >
    <Dialog
      :initialFocus = "focusRef"
      as = "div"
      @click.native.stop.prevent
      class = "relative z-50"
    >
      <div class = "fixed inset-0 overflow-y-auto">
        <div
          class = "flex min-h-full items-center justify-center p-4 text-center"
        >
          <DialogPanel
            @click.native.stop.prevent
            class = "pt-5 w-full max-w-xl overflow-y-auto transform overflow-visible rounded-2xl bg-white dark:bg-slate-800 p-6 align-middle shadow-xl transition-all"
          >
            THIS IS MODAL-2

            <span class = "text-black dark:text-white">Field-1</span>
            <input
              ref = "focusRef"
              v-model = "test.one"
              type = "text"
              class = "relative w-full h-full bg-gray-50 dark:text-black dark:bg-gray-700 dark:border-gray-600 border-gray-300 border rounded text-center block overflow-hidden"
            />

            <span class = "text-black dark:text-white">Field-2</span>
            <input
              v-model = "test.two"
              type = "text"
              class = "relative w-full h-full bg-gray-50 dark:text-white dark:bg-gray-700 dark:border-gray-600 border-gray-300 border rounded text-center block overflow-hidden"
            />

            <button class = "mt-4" @click = "closeModal">Close</button>
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>
</template>
  
  <script setup>
import { TransitionRoot, Dialog, DialogPanel } from "@headlessui/vue";

const props = defineProps({
  modal2: {
    type: Boolean, //Show/hide the modal based on the flag
    required: false,
  },
});

const emits = defineEmits(["closeModal"]);
const focusRef = ref(null);

//Reference variables
const modal2 = ref(props.modal2);
const test = ref({});

watch(
  () => props.modal2,
  async (newValue) => {
    modal2.value = newValue;
  }
);

const closeModal = () => {
  console.info("CLOSE MODAL-2");
  modal2.value = false;
  emits("closeModal");
};
</script>

Почему нажатие на DialogPanel2.vue автоматически закрывает предыдущее диалоговое окно DialogPanel1.vue? Я попытался удалить @close = "closeModal" из DialogPanel1.vue, что предотвратило бы закрытие DialogPanel1.vue, но из-за этого я не могу редактировать ни одно из полей в DialogPanel2.vue, что означает, что фокус все еще остается на DialogPanel1.vue, из-за чего я не могу получить доступ или фокус в DialogPanel2.vue. Следующие изменения в DialogPanel1.vue: <TransitionRoot appear :show = "modal1" as = "template">, но после этого я не могу получить доступ к полям ввода в DialogPanel2.vue.

Я до сих пор не могу определить основную причину и устранить ее, любые предложения будут очень полезны.

Проблема: Коды и песочница

Следующая проблема моя проблема GIF: Открытие диалогового окна Healdess UI (модальное) через другое диалоговое окно (модальное) автоматически закрывает предыдущее диалоговое окно (модальное)? (Добавлена ​​ссылка на воспроизведение CodeSandBox)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не могу прочитать полный код, но кажется, что в диалоговом окне используется что-то вроде «внешнего щелчка», который будет рассматривать любой щелчок, который не находится внутри элемента или его дочернего элемента, как «внешний щелчок» и запускает функцию закрытия. В вашем случае ваш <DialogPanel2> находится за пределами <DialogPanel1>, поэтому, когда <DialogPanel1> открывается и <DialogPanel2> также открывается, все, что не является дочерним элементом <DialogPanel1>, будет рассматриваться как находящееся за его пределами (в этом случае <DialogPanel2> считается за пределами <DialogPanel1>), таким образом, щелчок приведет к закрытию <DialogPanel1>.

Самое простое решение (в зависимости от вашего варианта использования) — переместить <DialogPanel2> внутрь <DialogPanel1>, чтобы он не считался внешним щелчком, например:

  <TransitionRoot appear :show = "modal1" as = "template" @close = "closeModal">
    <Dialog as = "div" class = "relative z-30">
      <div class = "fixed inset-0 overflow-y-auto">
        <div
          class = "flex min-h-full items-center justify-center p-4 text-center"
        >
          <DialogPanel
            class = "dark:bg-slate-800 w-full transform overflow-auto rounded-2xl bg-gray-200 p-6 text-left align-middle shadow-xl transition-all z-20"
          >
            THIS IS MODAL-1
            <button
              class = "flex secondary-button text-secondary dark:bg-transparent dark:hover:text-secondary dark:hover:bg-slate-700 mx-auto justify-center items-center rounded border focus:ring-0 focus:outline-none font-medium px-5 py-2.5 text-center min-w-[8rem] sm:min-w-[10rem] lg:min-w-[12rem]"
              @click = "openModal2"
            >
              MODAL-2
            </button>
            <DialogPanel2 :modal2 = "modal2" @closeModal = "hideModal2" /><!-- move it here-->
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>

Большое спасибо за ответ. Вы правы, это из-за мелочи, где я разместил его снаружи. Мне потребовались дни, чтобы понять это. Большое спасибо за ответ и теперь все работает так, как ожидалось.

BATMAN_2008 16.05.2024 09:24

Другие вопросы по теме