Vue3 및 PopperJS를 사용하여 드롭다운 메뉴 만들기

9836 단어
요소가 문서의 범위를 벗어날 때 자동으로 조정되는 드롭다운 메뉴를 만드는 데 한동안 어려움을 겪었습니다.

사용한 라이브러리:
  • PopperJS
  • Vue3
  • Tailwind

  • VueUse

  • <script setup>
    import { createPopper } from '@popperjs/core'
    
    const popperInstance = ref(null)
    const popcorn = ref(null)
    const tooltip = ref(null)
    
    onMounted(() => {
      useEventListener(popcorn.value, 'click', show)
    
      onClickOutside(popcorn.value, hide)
    
      popperInstance.value = createPopper(popcorn.value, tooltip.value, {
        placement: 'right-start',
        modifiers: [
          {
            name: 'offset',
            options: {
              offset: [0, 8]
            }
          }
        ]
      })
    })
    
    function show () {
      tooltip.value.setAttribute('data-show', '')
      popperInstance.value.update()
    }
    
    function hide () {
      tooltip.value.removeAttribute('data-show')
    }
    
    </script>
    
    <template>
      <div>
        <div
          ref="tooltip"
          class="
            tooltip
            bg-neutral-900
            rounded
            p-2
            text-white
            text-xs
            w-[100px]
          "
        >
          <div
            class="arrow"
            data-popper-arrow
          ></div>
    
          <ul>
            <li
              v-for="i in 5"
              :key="i"
              class="
                px-2 py-2
                bg-neutral-900 hover:bg-neutral-800
                rounded
              "
            >
              Hey
            </li>
          </ul>
        </div>
    
        <button
          ref="popcorn"
          class="
            popcorn
            bg-blue-500
            text-white
            px-3 py-2
            rounded
          "
        >
          Add
        </button>
      </div>
    </template>
    
    <style lang="scss" scoped>
    .tooltip {
      display: none;
    }
    
    .tooltip[data-show] {
      display: block;
    }
    
    .arrow,
    .arrow::before {
      position: absolute;
      width: 8px;
      height: 8px;
      background: inherit;
    }
    
    .arrow {
      visibility: hidden;
    }
    
    .arrow::before {
      visibility: visible;
      content: '';
      transform: rotate(45deg);
    }
    
    .tooltip[data-popper-placement^='top'] > .arrow {
      bottom: -4px;
    }
    
    .tooltip[data-popper-placement^='bottom'] > .arrow {
      top: -4px;
    }
    
    .tooltip[data-popper-placement^='left'] > .arrow {
      right: -4px;
    }
    
    .tooltip[data-popper-placement^='right'] > .arrow {
      left: -4px;
    }
    </style>
    

    좋은 웹페이지 즐겨찾기