当前位置: 首页 > news >正文

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

一、问题描述

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

<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

修改一下代码:

<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,这个是怎么来的呢?

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

相关文章:

  • 009:vue结合el-table实现表格行拖拽排序(基于sortablejs)
  • 微软发布安卓版Copilot,可免费使用GPT-4、DALL-E 3
  • 如何将语音版大模型AI接入自己的项目里(语音ChatGPT)
  • 计算机视觉与自然语言处理(Open AI)
  • 12月27日,每日信息差
  • 第四章 Consul服务注册与发现
  • Selenium库和ChromeDriver谷歌驱动最新版安装
  • 面试经典150题(50-53)
  • 垃圾收集器与内存分配策略
  • linux用户态与内核态通过字符设备交互
  • Appium+python自动化(二)- 环境搭建—下(超详解)
  • ajax的完整写法——success/error/complete+then/catch/done+设置请求头两种方法——基础积累
  • 右键菜单“以notepad++打开”,在windows文件管理器中
  • Spring实战系列(三)了解容器的基本实现
  • 数据库索引简析
  • JavaScript-如何实现克隆(clone)函数
  • 自己简单写的 事件订阅机制
  • 【comparator, comparable】小总结
  • canvas 高仿 Apple Watch 表盘
  • canvas绘制圆角头像
  • go append函数以及写入
  • Invalidate和postInvalidate的区别
  • JavaScript 基本功--面试宝典
  • Java比较器对数组,集合排序
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • springboot_database项目介绍
  • ucore操作系统实验笔记 - 重新理解中断
  • Vue.js源码(2):初探List Rendering
  • vue-loader 源码解析系列之 selector
  • Vue实战(四)登录/注册页的实现
  • web标准化(下)
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 关于extract.autodesk.io的一些说明
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 排序算法学习笔记
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 在weex里面使用chart图表
  • ​iOS实时查看App运行日志
  • #Java第九次作业--输入输出流和文件操作
  • #Z2294. 打印树的直径
  • $ git push -u origin master 推送到远程库出错
  • (20050108)又读《平凡的世界》
  • (70min)字节暑假实习二面(已挂)
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (阿里云万网)-域名注册购买实名流程
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (六)Hibernate的二级缓存
  • (四)库存超卖案例实战——优化redis分布式锁
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)socket Aio demo
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • .NET CORE 第一节 创建基本的 asp.net core
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler