vue中 点击事件的写法_vue中的事件:原生事件与自定义事件__Vue.js

模板编译 processAttrs

对于ast attributes处理(v-on/@)

利用onRE与dirRE来捕获事件

这里最重要的就是dynamic的判断,vue中可以用动态参数来命名事件名称,如@[prop],prop为data中的值。不过通常都是一个静态的事件名称如 @click

另一个核心方法就是addHandler

addHandler 往AST上添加events属性

1. 这里会对动态事件名称进行一些处理,也会对right,middle修饰符处理,另外对capture, passive, once的事件名称做了标记。分别添加 !, ~, # 符号。然后删除了对应属性值

2. 参数value为@click="handler"例子中的handler,在此处还在编译阶段handler本质上是一个string。然后对value做了处理,记录了模板解析event时候start和end的位置。

3. 对于单个事件有多回调函数绑定的情况,添加了一个important参数,以此来提前触发当前回调函数的执行

4. 另外,这里对鼠标的right和middle做了处理,在处理只有删除了对应属性值。对于键盘的事件没有做处理

AST -> code

修饰符:modifierCode

上面已经提到过了,本质上模板编译的时候会利用正则处理各种修饰符,然后根据对应关键词的生成代码。如常用的stop,prevent。

核心方法就是src/compiler/codegen/events.js的genHandler方法,以下是分析:

1. genHandlers

该方法就是简单的遍历events对象的键值对然后,对有无native修饰符与是否为dynamic事件做一个处理,其核心方法就是调用genHandler

genHandler

一些参数判断

事件函数的多种写法

在官方文档中演示了事件回调函数的多种写法,这些写法都在模板编译过程中进行了识别

下方三个正则表达式是模板编译时对event写法的判断依据,下面会有更详细的注释

1. 路径类写法

2. 箭头函数,匿名函数

3. 表达式 handler($event), a = 1

在vue中通常通过@click="handle($event)"来获取event对象,其实这里是vue在模板中做了一层包裹,将function($event){}套在handle($event)外部。

有修饰符的情况

修饰符在ast生成的过程中就已经捕获了,vue中对event事件的修饰符处理如下

先对修饰符做一个处理

最后座一层包裹,因为这里对键盘事件也做了处理,因此一定要拿到event对象

genCode

在处理完这些之后会生成字符串on:"…"/nativeOn:"…",最后生成render函数

组件初始化

组件初始化简单地说就是先对options做各种处理,最后执行渲染watcher,生成页面。

对native events的处理:

platforms/web/runtime/patch.js中有

const patch = createPatchFunction({nodeOps, modules})

modules源自:web/runtime/modules/index,导出含生命周期的对象**(非created周期)**

createPatchFunction

createPatchFunction往hooks内添加了updateDOMListeners,hooks为**并非是**组件的生命周期函数。在组件create与updated的时候就会触发updateDOMListeners函数。注册事件。

注意点: 这里create并非是组件created的**周期函数。**是在真实节点创建之后才会触发钩子,因此是可以拿到真实节点的。

updateDOMListeners

在调用modules.create的hook的时候触发了updateDOMListeners

其作用就是给用addEventListeners与removeEventListeners方法给真实dom节点添加事件。

updateListeners

将新旧事件进行对比更新。这里的add和remove可以给真实dom注册事件,也可以给组价注册事件。

占位符$vnode的真实dom事件:createComponent(部分)

对于组件而言,data.on赋值给listeners,把data.nativeOn赋值给data.on

data.on里面存放着的都是原生dom事件,组件内部的listeners都是用户自定义的事件。

因此,在组件patch过程中,创建组件的根节点的时候,就会把data.on内部的原生dom事件注册在dom上。

因此如果在h5元素使用native如 ,vue就会报错。这正是因为在这里做了处理,只有占位符vnode才可以有data.nativeOn的属性。是h5标签的节点不会调用createComponent方法,其data.on在创建节点的时候会绑定到节点上。

自定义事件(只针对组件间)

由createComponent函数可知,listeners存放了自定义事件。

在父子通讯的时候父组件只要v-on/@eventName,就可以监听到子组件emit出来的事件。

_init: initInternalComponent

创建子组件的时候会把占位符$vnode的$listeners传递给子组件的$options**(此时data.on已经是data.nativeOn,原始的data.on赋值给变量listeners)**

_init: initEvents

调用updateComponentListeners方法,最后还是调用了updateListeners方法(见前面文章注释)。

但是这里不同的是add和remove方法并非是document.addEventListener和document.removeEventListener

add/remove(vue中的发布订阅模式):

其实发布订阅模式比较简单,就不详细说明了,主要是add/remove方法。

小结

其实本质上,还是将父组件注册的回调函数传给了子组件的_events对象(让该函数存在于子组件中),但是看起来像是子组件调用了父组件的方法

eventBus

对于跨组件的组件通信,利用了vue实例可以有自身的_events对象,因此在Vue原型上创建一个空的vue实例,然后将vue所有组件上的函数都注册在这个实例对象的_events对象上,一次达到跨组件通信的目的

Vue.prototype.$bus=new Vue()

第三种情况:v-on="$listeners"

$listeners就是vnode.data.on的别称,因此通过$listeners就可以拿到父组件注册的非native事件。在爷孙组件通信的是可以使用$listeners通过父级组件将爷孙组件关联。

grand组件:

father组件:  // 此处是grand的事件

son组件:this.$emit(“test”) // 将father的$listeners传入son,而father的$listeners包含grand的事件,因此就将grand的事件传入了son中。

AST解析

在模板解析的时候会用正则匹配v-on,对于v-on="$listeners",vue将这种写法视为指令(directive),有不同的策略

on指令

_g

这里将$listeners对象与data.on进行合并,通过v-on指令我们可以一次性对组件注册多个事件。

最后

vue的事件基本上就是这样,其实这里面牵扯到了最核心的组件初始化和更新流程,关于此部分在本文中并没有明确说明,只是大概提了一下,一是要单纯靠文字说明费时费力(代码含有大量递归),而是本文重点是关注vue中的事件,在后面的更深入了解整个机制后会尝试说明写一篇vue组件初始化及更新的文章。

版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

作者: Simplyme0823

原文链接:https://juejin.im/post/6861206075744452622

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567063.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue点击其它侧边栏收缩_企业微信聊天侧边栏功能怎么开启?聊天侧边栏有什么用?...

腾讯的企业微信上线以来一直在默默的优化更新,今年8月份悄悄上新了聊天侧边栏功能。作为一款主打移动端办公的软件,企业微信上线聊天侧边栏有什么用?聊天侧边栏是啥聊天侧边栏是企业微信的一个全新功能,为了方便公司成员更好的与客…

下找到vue变量_Vue:npm run serve 到底做了什么?

前言 在 vue-cli2或者 vue-cli3 中,当我们创建好一个项目,我们要通过 npm run dev(vue-cli2的命令,vue-cli3之后用npm run serve,原理都一样,只不过是换了一下名字而已)运行一个项目。或者通过 npm run build 打包一个项目。那么问题来了,当我们在命令框中输入这两个命令…

python求最大值最小值_Python求可变参数的最大值最小值以及参数个数

求可变参数的最大值最小值以及参数个数 简介: 首先要做这个题,我们要使用函数来解决,这就要求我们要掌握函数的定义以及函数的调用。函数是一段具有特定功能的、可重用的,用来实现单一,或相关联功能的代码段。用函数名…

关于web服务器性能书籍,图书商城系统的Web服务器性能优化研究与实现

摘要:随着互联网技术的不断发展,特别是电子商务的不断发展,网上购物的需求也在不断的增加.根据《2017-2022年中国电子商务市场运行态势及投资战略研究报告》中指出2015年中国电子商务市场交易额规模16.4万亿元,增长22.7%.而其中网络购物增长36.2%,成为推动电子商务市…

侧边栏配置_企业微信上线“聊天侧边栏”功能,可在外部会话时快捷使用应用...

点击上方“蓝色字体”,选择 “设为星标”关键讯息,D1时间送达!8月7日消息,企业微信发布全新2.8.10版本,新增“聊天侧边栏”功能,且同时支持PC端与移动端。成员在外部会话中,可通过侧边栏使用应用…

python输入逗号分隔_命令行Python逗号分隔的用户输入int值

"2,3"是一个字符串,将其传递给函数不会使其表现为由,分隔的两个不同参数(如您所料)。在>>> def func(arg): ... print arg ... >>> func(a, b) a, b # arg is a variable that stores the passed string 您应该首…

vlc文件服务器局域网,vlc流媒体服务器配置

vlc流媒体服务器配置 内容精选换一换本节操作以Windows Server 2012操作系统的弹性云服务器为例介绍实现多用户登录的操作步骤。Windows server2012服务器默认能够支持两个用户同时远程登录,而通过配置远程桌面会话主机和远程桌面授权,即可实现多用户远程…

移动短信回执怎么开通_移动短信回执业务内容及资费介绍

短信回执业务是指移动客户向网内其他用户发送短信后,将会收到一条回执短信,内容包含接收方是否成功接收的状态报告信息,同时还可以收到我们提供的附加资讯信息的业务。附加资讯信息长度限为44个字符(含标点符号),内容涉及文化娱乐…

db2导入发生错误显示不是绝对路径_python编程常见错误总结

对于python初学者,在编程过程中常犯的错误及解决办法进行汇总和解决。勇哥希望编写此文能帮到大家。下边是勇哥结合例子给大家现身说法: 第一例:缩进错误(IndentationError)图1python对缩进很敏感,python用缩进来划分语句块,对于同…

服务器通电显示黄灯,服务器内存亮黄灯

服务器内存亮黄灯 内容精选换一换本文介绍了裸金属服务器BMS产品新特性和对应的文档动态,新特性将在各个区域(Region)陆续发布,欢迎体验。当您购买的云服务器规格无法满足业务需要时,可参考本章节变更规格,升级vCPU、内存。对于部…

mybatis mysql 调用存储过程 多个返回值_图解MyBatis的SQL执行流程(干货)

前言MyBatis可能很多人都一直在用,但是MyBatis的SQL执行流程可能并不是所有人都清楚了,那么既然进来了,通读本文你将收获如下:1、Mapper接口和映射文件是如何进行绑定的2、MyBatis中SQL语句的执行流程3、自定义MyBatis中的参数设置…

js获取下月时间_js 获取 本周、下周、本月、下月、本季度、下季度的开始结束日期...

js 获取 本周、上周、本月、上月、本季度、上季度的开始结束日期/*** 获取本周、本季度、本月、上月的开始日期、结束日期*/var now new Date(); //当前日期var nowDayOfWeek now.getDay(); //今天本周的第几天var nowDay now.getDate(); //当前日var nowMonth now.getMont…

华为手机显示解析服务器返回错误,ajax服务器返回错误

ajax服务器返回错误 内容精选换一换查询指定备份策略下的标签信息。URI格式GET /v2/{project_id}/backuppolicy/{policy_id}/tagsGET /v2/{project_id}/backuppolicy/{policy_id}/tags参数说明参数是否必选描述project_id是项目IDpolicy_id是策略ID请求示例GET /查询所有备份策…

已知弧长计算器_科学计算器,怎么用弧度计算弧长,请知道的举例说明,

展开全部大家好知道弧度的半径是6184.弦长是3120怎么算弧长,最好把详e69da5e6ba903231313335323631343130323136353331333363366236细的过程和结果发给我,用科学计算器要怎么按的方法写出来谢谢了要不然不懂的怎么用计算器算以后换了数字就不知道怎么算了…

pandas 对某一行标准化_Python中的神器Pandas,但是有人说Pandas慢...

如果你从事大数据工作,用Python的Pandas库时会发现很多惊喜。Pandas在数据科学和分析领域扮演越来越重要的角色,尤其是对于从Excel和VBA转向Python的用户。所以,对于数据科学家,数据分析师,数据工程师,Pand…

element引入的组件大小高度不对_Angular 2:尝试使用ElementRef访问组件高度时的奇怪行为...

我试图在Angular2中创建一个图像滑块,如下所示 .Slide Caption #1Slide Caption #2在我的滑块组件中,我希望能够获得每张幻灯片的高度,因此我使用ContentChildren获取滑块内的幻灯片列表,并且还将ElementRef导入到幻灯片组件以便访…

罗盘时钟编码代码_安全研究 | 利用macOS Dock实现代码的持久化执行

背景介绍近期,我一直在研究macOS上的一些持久化技术,尤其是如何利用低等级用户权限来修改文件以影响用户交互。对于macOS终端用户来说,交互最频繁的当属Dock了。在我的研究过程中,我发现了一个plist文件,它可以控制App…

mysql 共享锁_mysql有排他锁为什么还需要共享锁呢?

两把锁缺一不可,InnoDB 引擎中的四种隔离级别就是用 排他锁 共享锁 实现的。下面是个人理解,可能并不严谨。首先说一下并发可能产生的四种问题,如果你还不了解这四个问题,最好拿至少 20 分钟时间模拟一下场景。假设有两个事务A&a…

xpress-mp优化实例精选_量化研究每周精选-20170711

本周为大家精选了5项机器学习/深度学习在量化投资中的相关资源,机器学习/深度学习是偏实践性学科,只有不断实践才能有所收获,纸上得来终觉浅,绝知此事要躬行!BigQuant拥有海量的数据和主流开源框架,附能每一…

mac 删除分区 command r 选择网络_Mac使用必看基础篇,Mac快捷键大全,mac新手入门指南...

你是Mac新手吗?你对使用Mac电脑有疑问吗?你还不知道mac有哪些快捷键吗?别着急,来看看小编给大家准备的Mac使用必看基础篇——Mac快捷键大全,对于新手用户很有帮助哦!!一、开机相关命令快捷键C:从…