Vue源码 模拟Vue1(模板编译Complie的完成)

双向数据绑定

个人笔记,如有错误请见谅。

Vue.js的做法是采用数据劫持加发布者订阅模式,通过object.defineproperty()来劫持各个属性的getter与setter方法,setter监听值改变,getter返回改变后的值,在数据变动的时候,object.property()的set方法监听数据,通过get方法返回修改后的数据,通过Dep.notify方法通知订阅者(watcher),让订阅者去攻击视图更新数据。
在这里插入图片描述

模拟vue代码主要实现三件事

实现一个指令解析器Complie

实现一个数据监听器 Observer

实现一个Watcher去更新视图

实现一个proxy代理

实现complie

准备模板
在这里插入图片描述
在Mvue.js文件中
在这里插入图片描述
上面的querySelector前加上document.在这里插入图片描述
可以看到我们已经绑定了模板以及Mvue类。

接着需要遍历节点对其进行数据替换

每个都进行替换监听会引起页面的不断重毁和回流,这时候借助文档碎片对象,将其放入内存中减少重绘回流。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用for of 遍历模板所有节点
在这里插入图片描述
接着再一个一个放入文档碎片钟

在这里插入图片描述
在这里插入图片描述
可以看到左边的节点已经在文档碎片对象中了在这里插入图片描述
接着将节点追加到要插入的元素之中,即app
在这里插入图片描述
在这里插入图片描述
接着我们要在模板解析出来之前去编译。
所以我们先别追加。在追加前进行编译。在这里插入图片描述
将所有元素节点取出来了。
在这里插入图片描述
注意,我们这只是遍历第一层,故要判断在这里插入图片描述
在这里插入图片描述

有些模板有指令如v-mode,v-html,v-text,可以通过指令判断实现相对应操作。

先获取这个节点上的属性,里面就有指令在这里插入图片描述
通过node.attributes来获取在这里插入图片描述
在这里插入图片描述
通过强制转化为数组并且将其值遍历出来
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们只需要v-开头的属性,所以做个判断
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
我们需要通过dirname的不同做出不同的判断,需要用到策略模式

策略模式()

在这里插入图片描述
在这里插入图片描述
通过对象里面定义属性:方法来做出相对应的操作。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接着将先将模板加载到app里
在这里插入图片描述
在这里插入图片描述
可以看到,实现了模板编译的功能了。在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
也有一些值绑定的是A.A在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更新数据之后记得删除属性哦在这里插入图片描述
在这里插入图片描述
小总结:

对文本节点的编译 文本节点就是这些{ {}}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
。。。arg里面是个数组,第1个值就是去掉{ {}}的数据,在这里插入图片描述
在这里插入图片描述
##接着就是绑定事件了在这里插入图片描述

在这里插入图片描述

指向的不是window 在这里插入图片描述

处理v-bind

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

扫描二维码关注公众号,回复: 12846292 查看本文章

处理语法糖

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
至此,所有的编译解析功能实现完毕。

总结

解析编译,创建一个Vue类,将数据绑定在构造函数之上,并且在new一个Complie对象,去解析模板。所以要创建一个Complie对象,在Complie对象构造函数中,首先通过传进来的ID去获取模板,并创建一个文件对象,将模板里的节点取出来放进文件对象。再解析文件对象,将所有节点取出来,并且判断是元素节点(v-mode那些)还是文本节点{ {input}}那些,再做不同的操作。对元素结点的操作,获取属性attributes通过split,赋值解构等方法获取html,test,on,model等,通过策略模式,创建一个新类A,并在类里面定义几个方法,分别对应html,test,mode,on,bind等。然后通过调用A[‘test’](节点,属性值,Vue实例,事件名称 ),因为在一开始Vue的构造函数绑定了数据,故通过Vue.$data[属性值]即可获取相应内容,通过InnerHTML等方法赋值给节点,实现编译。

对于事件方法,只需要在一开始new Vue时,记得给methods加入方法,这样在A类的on里面就可以通过node.addEventListener(事件名,Vue.$methods.data.bind(Vue))来做出相对应的判断,记得方法要改变this指向。

对于bind,也是一样,node[属性]=Vue.$data.属性值,就可以动态绑定属性。

语法糖只是多做了几步判断,在这里插入图片描述

并不难实现。

猜你喜欢

转载自blog.csdn.net/lin_fightin/article/details/110704255