Как обновить всплывающее всплывающее окно с плавающим списком в Vue3?

Я использую Vue3, Pinia и библиотеку float-vue.

Я пытаюсь динамически создать всплывающее окно в позиции, которая зависит от других элементов, которые могут перемещаться в области просмотра. Для этого я размещаю фиктивный элемент div popup-anchor, к которому прикреплено всплывающее окно.

Когда я нажимаю на конкретный элемент, к которому хочу прикрепить всплывающее окно, этот элемент сохраняется в магазине Pinia.

Всякий раз, когда товар в магазине меняется, я вызываю setPosition() и show() для этого компонента Vue.

    selectedItemCoords (newValue, oldValue) {
      if (this.$refs.infoPopup) {
        if (newValue) {
          const pixelCoords = this.getPixelPositionOfItem()
          this.$refs.infoPopup.setPosition(pixelCoords)
          this.$refs.infoPopup.show();
        } else {
          this.$refs.infoPopup.close();
        }
      } else {
        console.info("Info Popupvalue not found")
      }
    }

Это работает хорошо, если между обновлениями предмета в магазине есть задержка (т. е. между обновлениями предмета нет значения), и я нажимаю где-нибудь в другом месте на экране. Однако, если я нажимаю один элемент за другим, всплывающее окно закрывается и не открывается снова, если только я не нажму что-то, что не является элементом, и значение хранилища не будет установлено на ноль.

Однако я хочу, чтобы всплывающее окно появлялось всякий раз, когда showPopup=true, т. е. если выбранные элементы меняются, я просто хочу переместить всплывающее окно и обновить его содержимое.

Ниже находится компонент Vue, который содержит фиктивную привязку и раскрывающийся список с плавающей запятой.

<template>
  <div
    id = "popup-anchor"
    ref = "anchor"
    class = "w-1 h-1 "
    :style = "{ position: 'absolute'}"
  >
    <Dropdown
      :shown = "showPopup"
      :distance = "1"
      :triggers = "[]"
      :popper-triggers = "[]"
    >
      <template #popper>
        <div
          v-if = "item"
          :item = "item"
          @share = "share"
        >
        item.text
        </div>
        <div
          v-else
          class = "loading-text"
        >
          Loading...
        </div>
      </template>
    </Dropdown>
  </div>
</template>

<script>
import { ref, computed } from 'vue';
import {Dropdown, hideAllPoppers, recomputeAllPoppers} from 'floating-vue';
import { useStore} from "@/store/store";

export default {
  components: {
    Dropdown,
  },
  props: {
    position: {
      type: Object,
      required: true,
      default: () => ({ top: '0px', left: '0px' }),
    },
  },
  setup(props, { expose }) {
    const anchor = ref(null);
    const showPopup = ref(false); 
    const storage = useStore();
    const item = computed(() => storage.item);

    // Method to toggle the visibility of the InfoPopup
    const show = () => {
      showPopup.value = true
      console.info('show', showPopup.value)
    };
    const close = () => {
      showPopup.value = false
      hideAllPoppers();
      console.info('close', showPopup.value)
    };
    const setPosition = (pixelCoords) => {
      anchor.value.style.top = `${pixelCoords[1]}px`;
      anchor.value.style.left =`${pixelCoords[0]}px`;
      recomputeAllPoppers();
    };

    const share = () => {
      console.info('share')
    };

    expose({ anchor, show, close , setPosition});

    return {
      anchor,
      show,
      close,
      share,
      showPopup,
      item,
    };
  },
};
</script>

«...позиция, которая зависит от других элементов...» — получите координаты этого базового элемента (смещение) и поместите всплывающее окно в нужную вам координату (с позицией: абсолютная. Посмотрите stackoverflow.com/questions/ 6802956/…

Михаил 28.06.2024 15:31

Но разве не это именно то, что я здесь делаю? Всплывающая привязка имеет абсолютную позицию, а в setPosition я задаю координаты.

FChris 01.07.2024 10:04
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

После обширной отладки я обнаружил, что проблема заключалась не в положении привязывающего div, а в том, что всплывающему окну нужно время, чтобы закрыться и снова открыться. Таким образом, установка showPopup = false, а затем showPopup = true в одном и том же галочке фактически скрывает всплывающее окно, но не открывает его повторно. Решение состоит в том, чтобы ввести задержку между обоими действиями.

const show = () => {
  if (showPopup.value = true) {
    // if the popup is already showing we have to close it 
    // and reopen it in the next tick so it can update the position 
    close();
    nextTick(() => {
      showPopup.value = true
    });
  } else {
    showPopup.value = true
  }
};

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