添加 eventListener 以模糊自定义组件上的事件? [英] Adding eventListener to blur event on custom component?

查看:19
本文介绍了添加 eventListener 以模糊自定义组件上的事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我正在尝试在自定义指令中使用 addEventListener 来监听事件并让事情发生.

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

<模板>

<输入v-绑定:值=值"v-on:input="$emit('input', $event.target.value)"v-on:blur="$emit('blur', $event.target.value)"/></div></模板>

我正在尝试通过自定义指令将 addEventListeners 添加到标签中以进行自定义验证.

在指令中,我使用 addEventListener 来监听来自输入字段的事件.

Vue.directive('custom-validator', {绑定:函数(el,绑定){el.addEventListener('blur', (event) => {//不触发});el.addEventListener('input', (event) => {///触发});},});

为什么模糊事件不触发,而输入事件触发?

如何让模糊事件触发?

解决方案

为什么模糊失败

你没有选择 blur 因为你没有指定 useCapture 参数.这是强制性的,因为 blur 事件确实不冒泡.所以添加 useCapture 可以解决你的问题:

el.addEventListener('blur', (e) => {//现在可以工作了}, 真的);//useCapture 是 addEventListener 的第三个参数


不要将 Native DOM 事件与 Vue 事件混淆

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

您可能会明白这一点,因为除了 v-on 上的那些 $emit() 之外,<input>触发原生事件blurinput.

所以你实际上有两种不同类型的 blur 事件和两种 input 事件(见下面的演示).


$emit() 怎么了?

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

.addEventListener() 用于原生 DOM 事件.它将监听 .dispatchEvent()s,而不是 $emit()s.

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

请参阅下面的演示.注意 .$on().addEventListener() 中的 e(事件)对象是不同的.

Vue.component('my-comp', {模板:'#styled-input-tpl',道具:['价值']});Vue.directive('我的指令', {绑定:函数(el,绑定,vnode){vnode.componentInstance.$on('blur', function (e) {console.log('received $on(blur) - 事件值:', event);});vnode.componentInstance.$on('input', function (e) {console.log('received $on(input) - 事件值:', e);});el.addEventListener('blur', (e) => {console.log('received NATIVE(blur) - event value:', e.target);}, 真的);//<========================================================= 重要el.addEventListener('输入', (e) => {console.log('received NATIVE(input) - 事件值:', e.target);});}})新的 Vue({埃尔:'#app'})

<script src="https://unpkg.com/vue@2.5.16/dist/vue.min.js"></脚本><模板 id="styled-input-tpl">

<输入v-绑定:值=值"v-on:input="$emit('input', $event.target.value)"v-on:blur="$emit('blur', $event.target.value)"/></div></模板><div id="app">编辑输入,聚焦并检查控制台.<my-comp v-my-directive :value="'edit me'"></my-comp></div>

I have a component called styled-input and it's an input with styles, icons, validation, etc.

I am trying to use addEventListener inside a custom directive to listen to events and make things happen.

<styled-input
    v-model=""
    v-on:input=""
    v-on:blur=""
></styled-input>

Internally: value is a prop (allowing for v-model binding outside)

<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>

I'm trying to addEventListeners to the tag through custom directives for custom validation.

<styled-input
    v-model=""
    v-custom-validator:credit-card
></styled-input>

Inside the directive I am using addEventListener to listen to events from the input field.

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

        el.addEventListener('input', (event) => {
            /// Fires
        });
    },
});

Why doesn't the blur event fire, while the input event fires?

How can I get the blur event to fire?

解决方案

Why blur fails

You are not picking the blur because you are not specifying the useCapture argument. It is mandatory because blur event does not bubble. So adding the useCapture would fix your problem:

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


Don't confuse Native DOM events with Vue events

From the your code (and see demo below), it may seem that when blur and input are triggered, the .addEventListener() picks what was emitted by $emit(). That is not the case.

You may get that idea because, besides those $emit()s at your v-ons, the <input> will also trigger the native events blur and input.

So what you actually have is two different kinds of events for blur and two for input (see demo below).


What is up with $emit()?

$emit() is internal to Vue. It is a part or every Vue instance events interface.

.addEventListener() is for native DOM events. It will listen to .dispatchEvent()s, not $emit()s.

To listen to Vue's $emit()s you must use Vue's .$on().

See demo below. Notice the e (event) object from the .$on() and from the .addEventListener() are different.

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'
})

<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>

这篇关于添加 eventListener 以模糊自定义组件上的事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆