You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constructor 从 descriptor 中抽取所需的参数,比如 el, value, expression 等
_bind 阶段调用 bind
_ 生成一个 _update 函数,负责调用 update
创建 this._watcher
我们直接贴上相关代码:
exportdefaultfunctionDirective(descriptor,vm,el){this.descriptor=descriptorthis.vm=vmthis.el=elthis.expression=descriptor.expression}Directive.prototype._bind=function(){vardef=this.descriptor.defif(typeofdef==='function'){this.update=def}else{extend(this,def)}if(this.bind)this.bind()if(this.update)this.update()if(this.update){constdir=thisthis._update=function(val,oldVal){dir.update(val,oldVal)}}else{this._update=function(){}}varwatcher=this._watcher=newWatcher(this.vm,this.expression,this._update)// v-model with inital inline value need to sync back to// model instead of update to DOM on init. They would// set the afterBind hook to indicate that.if(this.update){this.update(watcher.value)}}
这一篇,我们要实现一个事件绑定的功能:
那么为了实现这个功能,我们需要三步:
以
v-on
为例,如果碰到这样一个属性v-on:click=“hello”
指令的初始化流程如下?v-on
开头,那么就是一个绑定事件的指令,我们把相关的配置都存在 descriptor 中关于watcher的实现以及如何在directive中监听数据的变动,我们放到下一章来讲。
compileDirectives
在vue v1.0 版本及以前,是通过DOM API直接获取attributes的,并通过对name的匹配来判断是哪一类directive。在vue2中显然是通过virtual DOM的API来做的。
那么我们按照上面的步骤来说,compileDirectives 负责其中 1-4 步,即从attributes中生成一个 descriptors 列表:
上面这些代码都在
compile.js
中获取了
descriptors
之后,我们就可以逐个创建directive了,那么显然,我们需要实现一个 Directive类,他会接收这些 descriptor 并生成一个 directive 实例。这里需要重点说明一下,vuejs对每一个指令都会生成一个 directive 的实例,那么既然有 Directive 类了,那么
directives
下面的那么多指令是怎么回事呢?我们可以把
Directive
类当做一个父类,他定义了所有指令通用的方法:_bind, _update 以及生成 watcher。我们自己定义的比如v-on
指令的实现,其实可以看做是他的一个子类,其中的 bind 和 update 分别会被_bind
和_update
调用。当然,在语法上其实并不是父类和子类的关系,语法上来说,Directive会调用我们自定义的回调函数(update/bind) 仅此而已。Directive
类需要实现这几个功能:bind
_ 生成一个 _update 函数,负责调用
update
this._watcher
我们直接贴上相关代码:
这里注意创建watcher的代码,其中第三个参数
this._update
是watcher发现所观察的对象有更新的时候会触发的回调。因为我们还未实现
Watcher
类,所以这里可以先把Watcher
相关的代码注释掉。让我们实现一个自己的指令v-on
吧。这个指令最精简的实现非常简单:在
bind
的时候调用addEventListener
绑定一个回调即可。显然这么简单的处理是很不妥的,比如addEventListener不支持怎么办?如果用户更新了回调函数怎么办? 什么时候应该注销?,没关系,我们这里只是最精简版,暂时不用考虑这么全面。
调用
compile
以及new Directive
其实都是在lifecycle
中完成的,代码很简单大家直接去源码中看吧。赶紧绑定一个事件试试吧。
The text was updated successfully, but these errors were encountered: