vue是基于MVVM框架的,网上看到一个简版实现了vue的v-model,因为v-model相当于v-bind:value='***'和v-on:input='***',既有从数据层到视图层,又有从视图层到数据层的,比较好演示MVVM的运转。

上面demo实现的v-model效果,虽然功能不是很强大,但是却可以让我们简单看到MVVM的构建过程。

基础解析

首先要处理的是data部分:

我们需要遍历data,然后利用defineProperty劫持每个属性值的get/set,这个也是MVVM的核心所在:

然后我们将get/set和订阅者(Dep对象)关联起来,触发get时订阅(add),触发set时候发布(publish):

background Layer 1 text 订阅者对象 get set add publish

第二步我们需要解析html代码中含有v-model,或者带有{{**}}之类的符号:

通过el属性,找到容器元素,然后遍历里面的孩子节点,通过nodeType去识别。

我们需要把解析到的带有v-model或者{{***}}的节点,连同他们的关联的属性名(例如v-mode='abc'或者{{abc}}那么表示该节点和data中的abc变量关联),一起放入Watcher对象中,这个就好比将节点和变量关联起来。

background Layer 1 watcher1 node:input节点 name:text变量 update方法 watcher2 node:文本节点 name:text变量 update方法

例如上面的demo中我们创建了两个watcher。

关联订阅者和watcher

上面的基础解析主要是解析data对象和el下的节点,然后分别创建了各自的结构,现在的关键问题是两者如何关联起来。

关联的核心是在watcher在初始化的时候,设置了一个Dep.target = this,然后立马调用update,update调用get方法,进而是该watcher进入到订阅者里面去了。

图示如下,相当于watcher的初始化,让watcher得到了一张进入订阅者的门票:

background Layer 1 text get set 3.此时有Dep.target,加入 publish watcher node:input节点 name:text变量 update方法 1.初始化,设置Dep.target 2.调用update,触发text的get

两个watcher初始化后,全部进入了订阅者中,大致如下:

background Layer 1 text get set publish w2 add w1 触发update

订阅者的add方法相当于让watcher进入订阅者,但是它不是每次都会调用,只在watcher初始化的一瞬间会将watcher放入;订阅者的publish方法会遍历所有的watcher,并触发watcher的update方法,因为watcher里面包含了node,name,因此很容一将name的结果反应到node上。

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字