如何在vue指令中附加事件?

时间:2017-09-09 19:05:21

标签: vue.js directive

我需要使用指令将函数附加到元素。 我想用Vue方法 $ on 来做,但它不起作用。 当我使用 addEventListener 执行此操作时, event.target.value 在第一次输入后为我提供了未更改的值,第二次正常工作。 如何解决?

示例:http://jsfiddle.net/rjeu8Lc1/1/

directives: {
    rinput: {
      bind: function(el, bind, vnode) {
        el.addEventListener('input', function(event) {
          vnode.context.eventListenerCalled = true;
          // wrong value on the first input in event.target.value
          vnode.context.value = event.target.value; //changing data.value
        });
        vnode.context.$on('input', function(event) {
          // never executed =(
          vnode.context.vueEventListenerCalled = true;
        });
      }
    }
}

1 个答案:

答案 0 :(得分:0)

我同意Bert的意见,你不应该试图通过指令来调整Vue对象。另一方面,应该能够设置事件处理程序。在您的事件处理程序中,event.target.value没有更新的值。这似乎与您通过Vue附加输入处理程序的事实有关。当我删除@input="setDirty"时,它已得到修复。所以我认为第一课是:混合事件监听器可能会导致冲突。

除此之外,您实际上可以使用v-model

的传真



new Vue({
  el: '#app',
  data() {
    return {
      value: 'initial',
      eventListenerCalled: false
    }
  },
  directives: {
    rinput: {
      bind: function(el, bind, vnode) {
        el.value = bind.value;
        el.addEventListener('input', function(event) {
          vnode.context.eventListenerCalled = true;
          vnode.context.value = event.target.value; //changing data.value
        });
      }
    }
  }
})

<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <input v-rinput="value">
  <p>{{ value }}</p>
  <div v-if="eventListenerCalled"> Event Listener Called </div>
</div>
&#13;
&#13;
&#13;

这是一个用于说明错误的最小代码段。如果Vue样式的事件处理程序修改了数据,那么JS样式的事件处理程序(在Vue样式的处理程序之后调用)中event.target.value是错误的。

&#13;
&#13;
new Vue({
  el: '#app',
  data: {
    value: 'initial',
    isDirty: false
  },
  directives: {
    rinput: {
      bind: function(el, bind, vnode) {
        el.addEventListener('input', function(event) {
          console.log("Listener called", event.target.value);
        });
      }
    }
  },
  methods: {
    setDirty(event) {
      console.log("Dirty called", event.target.value);
      this.isDirty = !this.isDirty; // Without this, the listener works fine
    }
  }
})
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <input @input="setDirty" v-rinput="value" :value="value">
  <p>{{ value }}</p>
  <div v-if="isDirty"> Dirty function called </div>
</div>
&#13;
&#13;
&#13;