[Vuejs]-Vue: click outside directive is triggered inside the element with v-for

1๐Ÿ‘

I did some mathematics not to print several logs here:

this.counter++;
if (this.counter % this.myItems.length === 0) {
   console.log("showClickAway");
}

And, I changed this row:

if ((!(el === event.target || el.contains(event.target)) && event.target.className !== 'my-item'))

An example:

new Vue({
  el: '#app',
  data: {
    myItems: [1, 2, 3, 4, 5],
    counter: 0,
  },
  methods: {
    showClickAway() {
      this.counter++;
      if (this.counter % this.myItems.length === 0) {
        console.log("showClickAway");
      }
    }
  },
  directives: {
    "click-outside": {
      bind: (el, binding, vnode) => {
        el.clickOutsideEvent = (event) => {
          // here I check that click was outside the el and his children
          if ((!(el === event.target || el.contains(event.target)) && event.target.className !== 'my-item')) {
            // and if it did, call method provided in attribute value
            vnode.context[binding.expression](event);
          }
        };
        document.addEventListener("click", el.clickOutsideEvent);
      },
      unbind: (el) => {
        document.removeEventListener("click", el.clickOutsideEvent);
      },
    },
  },
});
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.my-item {
  width: 100px;
  height: 100px;
  background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app" style="display: flex; gap: 10px">
  <div v-for="(item, index) in myItems" v-click-outside="showClickAway" :key="item" class="my-item">
    {{ item }}
  </div>
</div>
๐Ÿ‘คcafertayyar

Leave a comment