为什么在 HeadlessUI Dialog/modal 中使用时 VueMultiselect 始终默认打开

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

我在 Nuxt 3 应用程序中使用 VueMultiselect。我在 Nuxt Headless UI Transition Dialog 模式中使用它。当我打开模式时,默认情况下会打开多选。

我有 2 个,其中一个始终开放。如果我只保留一个,那么它是打开的,但如果有 2 个,那么第一个是打开的。

组件/MultiSelect.vue:

<template>
  <label class="w-1/6 font-semibold text-base mb-1">{{ label }}</label>
  <div class="flex items-center dark:text-white">
    <VueMultiselect
      v-model="modelValue"
      :label="label"
      :placeholder="label"
      :options="options.map((i) => i.value)"
      :custom-label="(opt) => options.find((x) => x.value == opt).text"
      :searchable="true"
      :close-on-select="false"
      :allow-empty="false"
      :multiple="true"
      :preselect-first="false"
      :open-direction="'above'"
      :prevent-autofocus="true"
    >
    </VueMultiselect>
  </div>
</template>

<script setup>
import VueMultiselect from "vue-multiselect";

const props = defineProps({
  label: {
    type: String,
    required: false,
  },
  modelValue: {
    type: Array,
    required: false,
  },
  options: {
    type: Array,
    required: true,
  },
});

const emits = defineEmits(["update:modelValue"]);

const modelValue = ref(props.modelValue);

// Emit the updated modelValue when the selectedOption changes
const updateModelValue = () => {
  emits("update:modelValue", modelValue.value);
};

// Emit the updated modelValue when the selectedOption changes
watchEffect(() => {
  updateModelValue();
});
</script>

<style src="vue-multiselect/dist/vue-multiselect.css"></style>

以下是我对Dialog组件/MyDialog.vue的使用:

<template>
    <div class="flex-col items-center">
      <div class="mb-2">
        <button
          type="button"
          @click="openModal($event)"
          title="$t('pages.modal.sensor-title')"
          class="text-cyan-700 border-cyan-700 focus:ring-cyan-300 hover:bg-cyan-800 dark:hover:bg-cyan-600 dark:focus:ring-cyan-800 dark:border-cyan-500 dark:text-cyan-500 block rounded-full hover:text-white border focus:ring-4 focus:outline-none font-medium text-sm px-5 py-2.5 text-center mx-auto dark:hover:text-white"
        >
          Open
        </button>
      </div>
    </div>
    <TransitionRoot appear :show="showModal" 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-[70vw] sm:max-w-[70vw] md:max-w-[70vw] lg:max-w-[70vw] xl:max-w-[70vw] 2xl:max-w-[70vw]"
              >  
                <form @submit="onSubmit($event)">
                  <div class="flex items-center mt-10">
                    <div class="w-2/5">
                      <MultiSelect
                        :label="'Option1'"
                        v-model="selectedOption1"
                        :options="options1"
                      />
                    </div>
  
                    <div class="w-2/5 ml-5">
                      <MultiSelect
                        :label="'Option 2'"
                        v-model="selectionOption2"
                        :options="options2"
                      />
                    </div>
                  </div>
  
                  <!-- Submit/Cancel button for the modal -->
                  <button
                    type="button"
                    class="text-red-700 border-red-700 focus:ring-red-300 hover:bg-red-700 dark:hover:bg-red-500 dark:focus:ring-red-800 dark:border-red-500 dark:text-red-500 block rounded-full hover:text-white border focus:ring-4 focus:outline-none font-medium text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:hover:text-white"
                    @click="closeModal"
                  >
                    Submit
                  </button>
                </form>
              </DialogPanel>
            </TransitionChild>
          </div>
        </div>
      </Dialog>
    </TransitionRoot>
  </template>
  
  <script setup>
  import { ref, defineProps, onBeforeMount } from "vue";
  import {
    TransitionRoot,
    TransitionChild,
    Dialog,
    DialogPanel,
    DialogTitle,
    Switch,
  } from "@headlessui/vue";
  
  //Import static values for dropdowns
  import {
    options1,
    options2
  } from "~/public/Static/DefaultValues";
  
  
  const showModal = ref(false);
  const selectionOption1 = ref([]);
  const selectionOption2 = ref([]);
  
  // Open the modal on click of the button
  const openModal = () => {
    showModal.value = true;
  };
  
  // Close the modal on click of the button
  const closeModal = () => {
    showModal.value = false;
  };
  </script>
  
<style>
</style>

页面/View.vue:

<MyDialog />

单击按钮后打开对话框后,我会看到第一个多选下拉列表默认打开。如何解决这个问题?

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

知道这是因为对话组件将聚焦在第一个可聚焦元素上:

https://headlessui.com/react/dialog#managing-initial-focus

将焦点元素更改为其他元素,如下所示:

 <TransitionRoot appear :show="showModal" as="template" initialFocus="{completeButtonRef}">

以及相应的按钮:

<button type="button" @click="closeModal" ref="{completeButtonRef}">Submit</button>
© www.soinside.com 2019 - 2024. All rights reserved.