There are many common drop-down pop-ups on web pages, such as the user information popup shown below:

Clicking on the user’s image and name brings up a drop-down menu, and clicking on any blank area of the page (except for the popover itself) closes the popover. This example uses custom instructions to fulfill this requirement.

Let’s analyze how to do that.

This example has two features: clicking on the drop-down menu itself is not closed, and clicking on all areas outside the drop-down menu is closed. Clicking on all areas can be done by binding a Click event to the document, and filtering out whether it is clicking on an element inside the target element.

The following code applies only to vue.js 2.x:

  • index.html:
    
            
    <html>
    <head>
      <meta charset="utf-8">
      <title>Pull-down menu that can be closed from the outside</title>
      <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
      <div id="app" v-cloak>
          <div class="main" v-clickoutside="handleClose">
              <button @click="show = ! show">Click to display the drop-down menu</button>
              <div class="dropdown" v-show="show">
                  <p>Drop down the contents of the box and click on the outer area to close it</p>
              </div>
          </div>
      </div>
      <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
      <script src="clickoutside.js"></script>
      <script src="index.js"></script>
    </body>
    </html>Copy the code
  • Index. Js:

    var app = new Vue({
      el: '#app'.data: {
          show: false
      },
      methods: {
          handleClose: function () {
              this.show = false; }}});Copy the code
  • Clickoutside. Js:

    Vue.directive('clickoutside', {
      bind (el, binding, vnode) {
          function documentHandler (e) {
              if (el.contains(e.target)) {
                  return false;
              }
              if (binding.expression) {
                  binding.value(e);
              }
          }
          el.__vueClickOutside__ = documentHandler;
          document.addEventListener('click', documentHandler);
      },
      unbind (el, binding) {
          document.removeEventListener('click', el.__vueClickOutside__);
          deleteel.__vueClickOutside__; }});Copy the code
  • Style. CSS:
    [v-cloak] {
      display: none;
    }
    .main{
      width: 125px;
    }
    button{
      display: block;
      width: 100%;
      color: #fff;
      background-color: #39f;
      border: 0;
      padding: 6px;
      text-align: center;
      font-size: 12px;
      border-radius: 4px;
      cursor: pointer;
      outline: none;
      position: relative;
    }
    button:active{
      top: 1px;
      left: 1px;
    }
    .dropdown{
      width: 100%;
      height: 150px;
      margin: 5px 0;
      font-size: 12px;
      background-color: #fff;
      border-radius: 4px;
      box-shadow: 0 1px 6px rgba(0, 0, 2); }.dropdown p{
      display: inline-block;
      padding: 6px;
    }Copy the code