探究element-ui 2.15.8中<el-input>的keydown事件无效问题

一、问题描述

今天看到一个问题,在用Vue2+element-ui 2.15.8开发时,使用input组件绑定keydown事件没有任何效果。

html 复制代码
<template>
  <div id="app">
    <el-input v-model="content" placeholder="请输入"  @keydown="handelKeydown"/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      content: ''
    }
  },
  methods: {
    handelKeydown() {
      console.log('触发了Keydown事件!!!') // 实际不会触发
    }
  }
}
</script>

二、问题排查

我们直接调试代码,找到Vue2中事件初始化的地方initEvents


可以看到,我们的keydown事件其实是有记录到的,那么事件绑定的关键就在updateComponentListeners

在这里有两句代码很关键:

target$1 = vm;target$1 这个变量后面会提到,它就是vm,我们<el-input>组件的实例对象。

updateListenersupdateComponentListeners实际内部调用的事件更新处理,它里面如何执行,我们往下看:

可以看到,updateListeners里实现事件绑定的逻辑是在add函数内:

在这里我们再次看到了 target$1变量,从而keydown事件其实就是绑定在它上面了。

那么如果要使得keydown事件能够正常触发,<el-input>组件内部在<input>上应该要有@keydown,并$emit('keydown')。于是,到<el-input>组件源码内看看到底有没有这个:

可以看到<el-input>组件并没有绑定keydown事件。

接下来,修改一下它的源码来验证一下:


这时候不要直接去调试,如果直接修改源码后调试会发现没有任何效果,即使你重新启动服务。原因在于,加载的Element-UI目标文件并不是源码文件:

也就是,在main.js中使用的import Element from 'element-ui'导入的其实是node_modules\element-ui\lib\element-ui.common.js

所以这里我们还要再修改一下main.js

import Element from 'element-ui'替换成下面的代码:

复制代码
import Element from 'element-ui/src/index'

最后我们yarn serve重启一下服务,来验证一下:

三、解决方案

在实际开发中,不用去修改element-ui的源码也能使keydown事件生效,这里需要用到Vue的事件修饰符:navtive

修改一下代码:

html 复制代码
<el-input v-model="content" placeholder="请输入"  @keydown.native="handelKeydown"/>

同样可以看到它生效了。

这里你可能有疑问,native为何能使keydown生效了呢?我们简单看一下:


可以看到:

给普通vnode创建完dom后、和createChilren后,会调用invokeCreateHooks函数,这里面会执行属性、事件、指令等的create钩子函数(注意不是组件实例的create钩子函数)。

在事件的create钩子函数中,会调用updateDomLIsteners方法的updateListeners方法,因为是创建阶段,所以又会调用add方法,使用target.addEventListeners给目标真实dom元素添加监听事件。

另:

在最后调试的过程中,在invokeCreateHooks函数内,你可能会好奇:cbs.create[i_2]指向updateDOMListeners,这个是怎么来的呢?

关于这个其实来自于下面的代码:


相关推荐
用户059540174463 小时前
Redis 记忆存储踩坑实录:一个并发写入 Bug 让我排查了 4 小时
前端·css
小徐_23334 小时前
Wot UI 2.3.0 发布:二维码组件来了,Open Wot 与 wot-starter 同步更新
前端·微信小程序·uni-app
kyriewen4 小时前
Claude自己跑出去hack了3家公司——我为什么还在用它写代码
前端·ai编程·claude
IT_陈寒4 小时前
SpringBoot自动配置的坑,这次真踩疼我了
前端·人工智能·后端
子兮曰5 小时前
AI 浏览器 Agent 的安全困局:当自动化工具可以偷走你的登录态
前端·人工智能·后端
程序员黑豆5 小时前
鸿蒙应用开发之@Styles 装饰器:定义可复用的组件样式
前端·harmonyos
程序员码歌5 小时前
我全程用 AI开发了一款微信小游戏,上线了
android·前端·游戏开发
咩咩啃树皮5 小时前
第52篇:前端工程化完整体系精讲——Vite构建、模块化、打包原理、规范体系、面试终极通关
前端·面试·职场和发展
妙码生花5 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(四十八):菜单规则管理实现
前端·后端·ai编程
FogLetter5 小时前
当JavaScript学会“分身术”:异步编程的进化简史
前端·javascript·面试