Позиционирование списка

Поведение по умолчанию

При использовании CSS по умолчанию Vs Vue3 Select использует абсолютное позиционирование для отображения выпадающего меню. Корневой контейнер .v-select (компонент $el) используется в качестве относительного родительского элемента для выпадающего списка. Выпадающий список будет отображаться под $el независимо от доступного пространства.

Это работает в большинстве случаев, но вы можете столкнуться с проблемами при размещении в модальном режиме или в нижней части окна просмотра. Если вам нужен более точный контроль, вы можете использовать вычисляемое позиционирование.

Вычисляемое позиционирование

Если вы хотите получить больше контроля над отображением выпадающего списка или если у вас возникли проблемы с z-индексом, вы можете использовать логическую опцию appendToBody. Если включено, Vs Vue3 Select добавит выпадающий список к документу за пределами контейнера .v-select и позиционирует его с помощью Javascript.

Когда appendToBody имеет значение true, позиционирование будет обрабатываться функцией переданной через параметр calculatePosition. Эта функция отвечает за установку значений абсолютного позиционирования выпадающего списка top/left. Реализация по умолчанию размещает выпадающий список в том же положении, в котором он обычно отображается.

Интеграция Popper.js Integration

Popper.jsopen in new window это утилита объемом 3 кбайт для вычисления положения практически любого элемента DOM относительно другого.

Используя appendToBody и calculatePosition props, мы можем напрямую интегрироваться с popper для расчета позиционирования.

Смотрите Документацию Popperopen in new window где показан полный список модификаторов.

<script>
import countries from '../data/countries'
import {createPopper} from '@popperjs/core'

export default {
  data: () => ({ countries, placement: 'top' }),
  methods: {
    withPopper(dropdownList, component, { width }) {
      /**
       * We need to explicitly define the dropdown width since
       * it is usually inherited from the parent with CSS.
       */
      dropdownList.style.width = width

      /**
       * Here we position the dropdownList relative to the $refs.toggle Element.
       *
       * The 'offset' modifier aligns the dropdown so that the $refs.toggle and
       * the dropdownList overlap by 1 pixel.
       *
       * The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
       * wrapper so that we can set some styles for when the dropdown is placed
       * above.
       */
      const popper = createPopper(component.$refs.toggle, dropdownList, {
        placement: this.placement,
        modifiers: [
          {
            name: 'offset',
            options: {
              offset: [0, -1],
            },
          },
          {
            name: 'toggleClass',
            enabled: true,
            phase: 'write',
            fn({ state }) {
              component.$el.classList.toggle(
                'drop-up',
                state.placement === 'top'
              )
            },
          },
        ],
      })

      /**
       * To prevent memory leaks Popper needs to be destroyed.
       * If you return function, it will be called just before dropdown is removed from DOM.
       */
      return () => popper.destroy()
    },
  },
}
</script>