添加eventListener以模糊自定义组件上的事件?

Dav*_*lsh 3 javascript vue.js vue-component vuejs2

我有一个名为的组件styled-input,它是带有样式,图标,验证等的输入。

我试图addEventListener在自定义指令中使用以侦听事件并使事情发生。

<styled-input
    v-model=""
    v-on:input=""
    v-on:blur=""
></styled-input>
Run Code Online (Sandbox Code Playgroud)

内部: value是一个道具(允许在v-model外部绑定)

<template>
    <div>
        <input 
            v-bind:value="value"
            v-on:input="$emit('input', $event.target.value)"
            v-on:blur="$emit('blur', $event.target.value)"
        />
    </div>
</template>
Run Code Online (Sandbox Code Playgroud)

我正在尝试addEventListener通过自定义指令对标签进行自定义验证。

<styled-input
    v-model=""
    v-custom-validator:credit-card
></styled-input>
Run Code Online (Sandbox Code Playgroud)

在指令内部,我addEventListener用于侦听来自输入字段的事件。

Vue.directive('custom-validator', {
    bind: function(el, binding) {
        el.addEventListener('blur', (event) => {
            // Does not fire
        });

        el.addEventListener('input', (event) => {
            /// Fires
        });
    },
});
Run Code Online (Sandbox Code Playgroud)

为什么在输入事件触发时不触发模糊事件?

如何使模糊事件触发?

acd*_*ior 6

为什么模糊失败

您未选择,blur因为未指定useCapture参数。这是强制性的,因为blur事件不会冒泡。因此,添加useCapture将解决您的问题:

el.addEventListener('blur', (e) => {
  // it will work now
}, true); // useCapture is the third argument to addEventListener
Run Code Online (Sandbox Code Playgroud)


不要将本机DOM事件与Vue事件混淆

从您的代码中(并参见下面的演示),似乎在触发blur和时input.addEventListener()选择了发出的内容$emit()事实并非如此

你可能会有这种想法,因为,除了那些$emit()s的你v-ons时,<input>同时触发本地事件blurinput

因此,您实际拥有的是两种不同的事件,blur而两种是input(请参见下面的演示)。


怎么了$emit()

$emit()在Vue内部。它是Vue实例事件接口的一部分或每个接口

.addEventListener()用于本机DOM事件。它将监听.dispatchEvent()s而不是$emit()s。

要收听Vue的,$emit()您必须使用Vue的.$on()

请参阅下面的演示。注意e从(事件)对象.$on(),并从.addEventListener()不同

Vue.component('my-comp', {
  template: '#styled-input-tpl',
  props: ['value']
});

Vue.directive('my-directive', {
  bind: function (el, binding, vnode) {
    vnode.componentInstance.$on('blur', function (e) {
      console.log('received $on(blur) - event value:', event);
    });
    vnode.componentInstance.$on('input', function (e) {
      console.log('received $on(input) - event value:', e);
    });
    
    el.addEventListener('blur', (e) => {
      console.log('received NATIVE(blur) - event value:', e.target);
    }, true);  // <======================================================= IMPORTANT
    
    el.addEventListener('input', (e) => {
        console.log('received NATIVE(input) - event value:', e.target);
    });
  }
})

new Vue({
  el: '#app'
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@2.5.16/dist/vue.min.js"></script>

<template id="styled-input-tpl">
    <div>
        <input 
            v-bind:value="value"
            v-on:input="$emit('input', $event.target.value)"
            v-on:blur="$emit('blur', $event.target.value)"
        />
    </div>
</template>

<div id="app">
  Edit the input, focus out, and check the console.
  <my-comp v-my-directive :value="'edit me'"></my-comp>
</div>
Run Code Online (Sandbox Code Playgroud)