vue源码深入分析,步骤分层次解读,vue点击事件详解

大家好,在网上看到过很多vue源码的解析,大多是copy和摘抄的,少有自己的理解,所以下决心花时间整理一遍自己对vue源码的理解。我只是一个普普通通的码农,如果本文有写的不对之处,希望各路大神指正,谢谢!

vue版本:2.5.17

源代码相关链接:https://cdn.bootcdn.net/ajax/libs/vue/2.5.17/vue.js

首先,本人采取的是最简单的debugger调试方法,按照步骤与逻辑分层次解析vue源码,我认为这是最快、最简单、也是最有效的方法。本文使用的vue调试代码如下:

<div id="main">
  <h1>count: {{times}}</h1>
  <p @click="cons">{{text}}</p>
</div>
<script src="./vue2.5.17/dist/vue.js"></script>
<script>
  var timeId = null
  var vm = new Vue({
    el: '#main',
    data: function () {
      return {
        times: 1,
        text: "我的"
      };
    },
    created: function () {
      var me = this;
      timeId = setInterval(function () {
        me.times++;
      }, 1000);
    },
    methods: {
      cons() {
        console.log(6211)
        debugger
        this.text = "你的"
      }
    }
  });

这是一个非常简单的例子,但可以很好地帮助我们解读vue的整个运行流程。

vue点击事件篇

事件监听

在这里插入图片描述
主要是在原型链上绑定四种事件监听:$on(点击事件)、$once(单次点击事件)、$off(移除事件)、$emit(抛出或触发自定义的事件)等监听。

dom元素(标签)上的事件
举例:<div @click="test01"></div>
v-on指令(该指令经常简写为@)监听DOM事件,并在触发时运行以下代码

通过processAttrs()解析属性时
在这里插入图片描述
Vue利用正则表达式dirREonRE匹配到该dom元素及相关事件,之后添加属性。
在这里插入图片描述
这里说明一下,因为Vue初始化时,调用initEvents(vm)对事件进行初始化,所以之后我们通过点击的方式去触发事件,原生绑定nativeBind就会触发事件,改变this的指向后,找到对应的事件方法,解析并执行。
在这里插入图片描述
initEvents方法在vm上创建一个_events对象,用来存放事件。
接下来就调用initState()方法初始化事件,相关代码段:

在这里插入图片描述
opts的methods属性里有我们自定义的test测试方法,然后就会执行initMethods。
在这里插入图片描述
请注意:这里最关键的一句代码,initMethods遍历定义的methods,通过调用bind改变函数的this指向,修饰了事件的回调函数,组件上挂载的事件都是在父作用域中的。
在这里插入图片描述
nativeBind方法里的bind改变了函数的this指向,这里的this指向ctx的地址值
Bind改变this指向的原理可参考:https://www.cnblogs.com/xljzlw/p/3775162.html

在这里插入图片描述
Ast的解析过程可参考:https://segmentfault.com/a/1190000015848917

然后通过add$1方法里的addEventListener将事件绑定到target(目标)标签上
在这里插入图片描述
组件的点击事件

<div @click.native="test01"></div>

<child-test>标签定义了click事件,若click事件没加修饰符.native,点击按钮不出发任何事件,这里.native修饰符的作用就是在原生dom上绑定事件。

如果不添加.native的的事件解析过程与上文相同,而添加了.native之后,v-on的事件会被放到nativeOn数组中,解析后的render如下图所示:
在这里插入图片描述
我们再来分析一下事件的初始化,
调用genHandlers方法时,会先判断该事件是否为native,如果是,解析的事件字符串就会用'nativeOn{}'字符串包裹。

在这里插入图片描述
html解析成vnode之后会调用createComponent进行处理。
在这里插入图片描述
在这里插入图片描述
createComponent方法里会.native修饰符的事件放在data.on上面。接下来data.on上的事件(本文中的alert(‘001号被点了!’);)会按普通的html事件继续执行下方代码。
在这里插入图片描述
最终通过target$1.addEventListener添加事件监听。
而标签内没有.native的修饰符调用的是$on方法。
在这里插入图片描述
updateListeners又调用了add方法
在这里插入图片描述
小结:
对于普通html元素和在组件标签内添加了.native修饰符的事件,都通过target1.addEventLister()来挂载事件。而定义在组件上的事件会调用原型上的on等方法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值