Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does using the same vue directive multiple times call updates on all of them?

I've created a vue directive that I'm attaching to multiple input elements on the same page, and have noticed that when I start typing in one of them, the 'update' event fires for all elements in the page. I had expected to only have one event, for the particular element that I had updated.

My question is, Is there a way to prevent the event firing, or filtering the events so that I can handle only the input that is changing?

Heres the code for my directive and view:

Vue.directive('test', {
  bind: (el) => {
    console.log(el.id + " bound")
  },
  update: (el) => {
    console.log(el.id + " updated")
  }
})

new Vue({
  el: "#app",
  data: {
    testval1: null,
    testval2: null,
  },
  methods: {
  }
})

and the template:

<div id="app">
  <input id="testinput1" v-model="testval1" v-test />
  <input id="testinput2" v-model="testval2" v-test />
</div>

Here is a JSFiddle of the issue: https://jsfiddle.net/eywraw8t/415288/

In this JSFiddle, you can see in the console that if you type into the input field, it fires the update for both input fields.

like image 980
Matt M Avatar asked Oct 12 '18 03:10

Matt M


People also ask

How many types of the directive are used in VUE JS?

Directives are instruction for VueJS to do things in a certain way. We have already seen directives such as v-if, v-show, v-else, v-for, v-bind , v-model, v-on, etc. In this chapter, we will take a look at custom directives. We will create global directives similar to how we did for components.

What's Vue JS directive?

Vue. js Directives are special HTML attributes that allow us to manipulate the DOM. Directives are very powerful and we use them every day. Common directives are v-if , v-for and v-model . The course covers all you need to know to be able to create your own, custom vue.


Video Answer


1 Answers

I think the best way is to use bind. Your directive there will be a directive that works on every element with v-test directive specified. Here is simple approach to solve your issue

Vue.directive('test', {


  bind: (el) => {
    console.log(el.id + " bound")
    const handler = (e) => {
        console.log('e', e.target)
      if (el == e.target) {
        console.log(el.id + " firing")
      }
    }
    el.vueTest = handler
    // add Event Listeners
    document.addEventListener('input', handler)
  },
  unbind (el, binding) {
    // Remove Event Listeners
    document.removeEventListener('input', el.vueTest);
    el.vueTest = null;
  }
})

Hope this will help you :)

like image 183
Indra Kusuma Avatar answered Nov 15 '22 00:11

Indra Kusuma