在同一页面中使用多个对话框会引发错误:<FocusTrap />

问题描述 投票:0回答:1

我正在我的应用程序中创建一个可重用的对话框模式,当我在页面中使用它一次时它工作正常,但当我使用多次时,我会收到错误:

There are no focusable elements inside the <FocusTrap />

以下是我的 Vue3/Nuxt 3 应用程序中 HeadlessUI 中的可重用对话框组件:

ExtensionModal.vue

<template>
  <div class="flex-col items-center">
    <div class="mb-2">
      <button
        type="button"
        @click="openModal"
        class="block rounded-full text-blue-700 hover:text-white border border-blue-700 hover:bg-blue-800 focus:ring-0 focus:outline-none focus:ring-blue-300 font-medium text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:hover:bg-blue-600 dark:focus:ring-blue-800"
      >
        {{ buttonLabel }}
      </button>
    </div>
  </div>

  <TransitionRoot appear :show="showExtensionModal" as="template">
    <Dialog as="div" @close="closeModal" class="relative z-10">
      <TransitionChild
        as="template"
        enter="duration-300 ease-out"
        enter-from="opacity-0"
        enter-to="opacity-100"
        leave="duration-200 ease-in"
        leave-from="opacity-100"
        leave-to="opacity-0"
      >
        <div class="fixed inset-0 bg-black bg-opacity-25" />
      </TransitionChild>
      <div
        class="fixed h-fit inset-0 overflow-y-auto flex items-center justify-center"
      >
        <div
          class="fixed inset-0 overflow-y-auto flex items-center justify-center"
        >
          <TransitionChild
            as="template"
            enter="duration-300 ease-out"
            enter-from="opacity-0 scale-95"
            enter-to="opacity-100 scale-100"
            leave="duration-200 ease-in"
            leave-from="opacity-100 scale-100"
            leave-to="opacity-0 scale-95"
          >
            <DialogPanel
              class="flex-grow w-full h-fit transform overflow-visible rounded-2xl bg-gray-200 dark:bg-slate-800 p-6 text-left align-middle shadow-xl transition-all max-w-[90vw] sm:max-w-[80vw] md:max-w-[70vw] lg:max-w-[60vw] xl:max-w-[50vw] 2xl:max-w-[40vw]"
            >
              <DialogTitle
                as="h3"
                class="flex text-lg font-medium leading-6 text-gray-900 justify-center dark:text-white"
              >
                {{ buttonTitle }}
              </DialogTitle>

              <form @submit="onSubmit($event)">
                  <div class="flex mt-5">
                    <div class="w-full z-40">
                      <select
                        v-model="element"
                        class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                      >
                        <option
                          v-for="option in extensionTypes"
                          :value="option.value"
                          :key="option.value"
                        >
                          {{ option.text }}
                        </option>
                      </select>
                    </div>
                  </div>

                <!-- Submit/Cancel button for the modal -->
                <FormSubmit @submit="onSubmit" @close="closeModal" />
              </form>
            </DialogPanel>
          </TransitionChild>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>
</template>

<script setup>
import {
  TransitionRoot,
  TransitionChild,
  Dialog,
  DialogPanel,
  DialogTitle,
  Switch,
} from "@headlessui/vue";

const props = defineProps({
  buttonTitle: {
    type: String, // title for the field
    required: false,
  },
  buttonLabel: {
    type: String, // label for the button
    required: false,
  },
});

const emits = defineEmits(["onSubmit"]);

const extension = ref({});
const showExtensionModal = useState("showExtensionModal", () => false);
const extensionTypes = useState("extensionTypes", () => [
  { value: "extensionElement", text: "Element" },
]);
const dataTypes = useState("dataTypes", () => [
  { value: "string", text: "String" },
  { value: "complex", text: "Complex" },
]);

//Open the modal on click of the button
function openModal() {
  showExtensionModal.value = true;
}

//Close the modal on click of the button
function closeModal() {
  showExtensionModal.value = false;
}

//Function to update the value of the object based on DropDown value change
function onItemChange(fieldName, value) {
  extension.value = {};
  extension.value[fieldName] = value.value;
}

//Function to store and return the value on submission
function onSubmit(event) {
  event.preventDefault();
  console.log("Sumitted : " + JSON.stringify(extension.value, null, 4));
  emits("onSubmit", extension.value);
  closeModal();
}
</script>

<style>
</style>

我在我的应用程序中使用此组件两次:

pages/view.vue

<template>
    <div>
  
      <div class="my-2 mx-2 px-2 pb-0">
        <div class="flex gap-2 h-16 float-right">
          <ExtensionModal
            :buttonTitle="$t('pages.modal.userExtension-btt-title')"
            :buttonLabel="$t('pages.modal.userExtension-btt-label')"
          />
  
          <ExtensionModal
            :buttonTitle="$t('pages.modal.ilmd-btt-title')"
            :buttonLabel="$t('pages.modal.ilmd-btt-label')"
          />

        </div>
      </div>
    </div>
  </template>
  
  <script setup>
  import { Icon } from "@iconify/vue";
  </script>
  
  <style>
  </style>

当我单击按钮打开模式时,我收到错误:

There are no focusable elements inside the <FocusTrap />`

安装和其他所有内容都是正确的,因为当我在

view.vue
页面中仅使用子组件的一个实例时,它工作正常:

<ExtensionModal
            :buttonTitle="$t('pages.modal.userExtension-btt-title')"
            :buttonLabel="$t('pages.modal.userExtension-btt-label')"
          />

仅当我在应用程序中多次使用它时,我才会收到错误。不知道我在这里做错了什么。我需要传递任何其他参数或添加任何缺失的信息吗?

vue.js nuxt.js vuejs3 nuxtjs3 headless-ui
1个回答
0
投票

你修好了吗?我也遇到同样的情况

© www.soinside.com 2019 - 2024. All rights reserved.