[컴] vuejs 에서 dropdown menu

확장 / 추가 메뉴 버튼 / 다양한 메뉴

vuejs 에서 dropdown menu

  • 동작 : button 을 누르면, dropdown menu 가 보이고, button 을 누르면 사라진다. 또는 dropdown 외의 곳을 click 해도 메뉴가 사라진다.
참고로 아래 v-click-outside 를 사용하는 경우 버튼 이외의 click 이 발생하면 항상 동작하게 된다. 이 부분에 대한 처리를 위해서, listener 를 remove 를 따로 해줘야 할 수도 있다.
 
<template>
<div class="ddmenuWarpper" v-click-outside="onClickOutside">
  <button class="ddmenuBtn" @click="onClickButton">
    show submenu
  </button>
  <div class="dropdownMenu">
    <div class="bubbleArrow"></div>
    <div>sub menu 1</div>
    <div>sub menu 2</div>
  </div>
</div>
</template>

<script>
import Vue from "vue";

// 'v-click-outside' directive 생성, 
Vue.directive("click-outside", {
  bind(el, binding, vnode) {
    el.clickOutsideEvent = (event) => {
      if (!(el === event.target || el.contains(event.target))) {
        vnode.context[binding.expression](event); // onClickOutside
      }
    };
    document.body.addEventListener("click", el.clickOutsideEvent);
  },
  unbind(el) {
    document.body.removeEventListener("click", el.clickOutsideEvent);
  },
});

const _ = {
  name: 'ButtonWithDropdown',
  props: {},
  data() {
    return {
      isOpen: false,
      isDarkMode: false,
    }
  },
  methods: {
    onClickOutside(evt) {
      this.isOpen = false
    },
    onClickButton(evt) {
      this.isOpen = !this.isOpen
      evt.stopPropagation()
    },
  },
  watch: {},
}

export default _
</script>

<style>
.ddmenuWarpper {
    position: relative;
    width: 44px;
    height: 27px;
    border-radius: 8px;
    background: white;
    border: 1px solid #eee;

}
.ddmenuWarpper .ddmenuBtn {
    border: none;
    font-size: inherit;
    background: none;
    outline: none;
    border-radius: 4px;
    position: absolute;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    padding: 0;
    margin: 0;
    line-height: 1;
    width: 100%;
    height: 100%;
    z-index: 2;
    cursor: pointer;
}
.ddmenuWarpper .dropdownMenu {
    position: absolute;
    top: 150%;
    min-width: 100px;
    min-height: 10px;
    border-radius: 8px;
    border: 1px solid #eee;
    background: white;
    padding: 10px 30px;
    z-index: 99;
    animation: aniMenu 0.3s ease forwards;
}
.ddmenuWarpper .dropdownMenu .bubbleArrow:before {
    content: "";
    width: 0px;
    height: 0px;
    position: absolute;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-top: 10px solid transparent;
    border-bottom: 10px solid #eee;
    right: 80%;
    top: -20px;
}

.ddmenuWarpper .dropdownMenu .bubbleArrow:after {
    content: "";
    width: 0px;
    height: 0px;
    position: absolute;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-top: 10px solid transparent;
    border-bottom: 10px solid #fff;
    right: 80%;
    top: -19px;
}
@keyframes aniMenu {
    from {
      transform: translate3d(0, 30px, 0);
    }
    to {
      transform: translate3d(0, 20px, 0);
    }
}
</style>

Reference

  1. How to Detect Clicks Outside an Element with Vue.js? - The Web Dev

댓글 없음:

댓글 쓰기