摘要:写文章不容易,点个赞呗兄弟专注源码分享,文章分为白话版和源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于版本如果你觉得排版难看,请点击下面链接或者拉到下面关注公众号也可以吧原理源码版之绑定标签事件这里的绑定
写文章不容易,点个赞呗兄弟
专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧
研究基于 Vue版本 【2.5.17】
如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧
【Vue原理】Event - 源码版 之 绑定标签DOM事件
这里的绑定DOM事件,是指绑定原生标签的DOM 事件
因为组件也是可以绑定原生DOM事件的,不过并不是在原生标签上绑定,而是直接在组件上绑定的,这部分内容会其他文章说明
或者你可以看看白话版先了解下Event
【Vue原理】Event - 白话版
怎么解析由于解析不是本内容的重点,所以在这里就不谈怎么解析的了,只说一个结果就好了
现在有这么一个模板
模板被解析成这样的渲染函数
渲染函数执行之后,得到这样的 VNode
你可以看到,事件被存放到了 vnode.data 上
Vnode 有疑惑的可以看介里
【Vue原理】VNode - 源码版
怎么绑定既然模板已经被解析完成了,下一步就是开始绑定了
好的,继续来走流程
在 template 解析得到 Vnode 之后,下面就会进行DOM生成挂载
而绑定事件,就发生在开始挂载,创建DOM 之后 的阶段
挂载时从 Vue.prototype._update 这个函数开始的
挂载的流程,可以看看这篇文章
从模板到DOM的简要流程
1、开始挂载VNode创建完毕,传入 Vue.prototype._update 这个方法中,进行比对新旧VNode
然后生成DOM挂载页面
其中需要生成DOM,调用的方法是 createElm
2、创建DOM创建DOM,在Vue 中调用的是 createElm 这个方法
看过以前的文章的,都知道这个函数的作用是
根据 vnode 生成DOM,并且进行挂载
而在 createElm 中,会调用一个函数去 处理模板上相关的数据
比如处理属性,类名,style 之类的,其中DOM事件也是在这里处理的
这个函数就是 invokeCreateHooks,继续往下看
function createElm(vnode) { // ....处理组件 // ....生成标签对应dom // ....递归遍历子节点 invokeCreateHooks(vnode); // ....插入DOM 节点 }3、处理数据
上面源码中出现的 invokeCreateHooks 这个方法是用来处理数据的
每种数据(style,class等),都有一个专门的函数去进行处理
而 invokeCreateHooks,就是负责执行每种数据的处理函数,很简单,就是一个单纯遍历执行的过程
其中就包括处理 DOM 事件的函数,便是 updateDOMListeners
function invokeCreateHooks( vnode ) { /** * 执行的函数包括下面这么多 * cbs = [ * create:[ * updateAttrs, updateClass, * updateDOMListeners, updateDOMProps, * updateStyle, create, updateDirectives * ] * ] **/ for (var b = 0; b < cbs.create.length; ++b) { // 其中会调用 updateDOMListeners // emptyNode 是空节点,因为这里是初始化才会调用的 // 所以旧节点是空节点 cbs.create[b](emptyNode, vnode); } .... }
下面看下 处理DOM 事件的函数
4、绑定DOM事件简化的源码,看起来顺眼多了,主要逻辑一清二楚,主要就是绑定事件和解绑事件,你看下喽,挺简单的
function updateDOMListeners(oldVnode, vnode) { var on = vnode.data.on || {}; var oldOn = oldVnode.data.on || {}; var target = vnode.elm; // 遍历绑定的事件 for (name in on) { newHandler = on[name]; oldHandler = oldOn[name]; // 没有旧事件,就直接添加新事件 if (typeof oldHandler === "undefined") { // 给事件回调包装一层 target.addEventListener(name, function(){ on[name]() // 执行保存在vnode的事件 }); } // 新事件和旧事件不一样,替换旧事件 else if (newHandler !== oldHandler) { on[name] = newHandler; } } // 移除旧事件 for (name in oldOn) { // 旧事件不存在新事件中,直接移除 if (typeof on[name] === "undefined") { target.removeEventListener( name, oldOn[name] ); } } }
看看绑定函数和 移除函数,就只是简单使用 addEventListener 和 removeEventListener,我没看之前还以为 Vue 写了很多兼容,没想到就是这么简单完成这个功能
有点惊讶,反正简单也好吧,哈哈哈,简单看着就是苏胡啊~~
绑定逻辑很简单1、新旧事件相同,替换旧事件
2、新事件不存在旧事件中,绑定新事件
3、旧事件不存在新事件中,解绑旧事件
其中会给回调事件函数包装一层函数,然后在内部执行绑定的回调,包装一层的原因是,为了在回调中做点其他操作(比如宏微任务的处理等,这里为了简单去掉了)
并且旧事件回调改了的时候,就更加方便了,不用解绑再绑定,直接把执行的事件回调 on[name]替换掉就ok了
好的,原生标签绑定DOM 事件到这里就完成了,希望对大家有所帮助
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/105487.html
摘要:写文章不容易,点个赞呗兄弟专注源码分享,文章分为白话版和源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于版本如果你觉得排版难看,请点击下面链接或者拉到下面关注公众号也可以吧原理源码版之绑定组件事件上一篇已经 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于...
摘要:写文章不容易,点个赞呗兄弟专注源码分享,文章分为白话版和源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于版本如果你觉得排版难看,请点击下面链接或者拉到下面关注公众号也可以吧原理白话版事件是我最感兴趣的东西之 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于...
摘要:首先,兄弟,容我先说几句涉及源码很多,篇幅很长,我都已经分了上下三篇了,依然这么长,但是其实内容都差不多一样,但是我还是毫无保留地给你了。 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也...
摘要:写文章不容易,点个赞呗兄弟专注源码分享,文章分为白话版和源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于版本如果你觉得排版难看,请点击下面链接或者拉到下面关注公众号也可以吧原理源码版之绑定组件自定义事件组件 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于...
摘要:写文章不容易,点个赞呗兄弟专注源码分享,文章分为白话版和源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于版本如果你觉得排版难看,请点击下面链接或者拉到下面关注公众号也可以吧原理源码版之拼接绑定的事件今天我们 写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究...
阅读 3382·2023-04-25 19:39
阅读 3784·2021-11-18 13:12
阅读 3618·2021-09-22 15:45
阅读 2409·2021-09-22 15:32
阅读 691·2021-09-04 16:40
阅读 3683·2019-08-30 14:11
阅读 1820·2019-08-30 13:46
阅读 1540·2019-08-29 15:43