我是如何写 vue 源码的:思路篇

  • A+
所属分类:未分类

看了那么多篇文章,我发现很多文章只会告诉你他是怎么写的而不会告诉你他是怎么想的。而我认为,能否写出代码最主要的是如何构思的?为什么有的人能把代码写的很优雅而有的人写的却很臃肿?为什么有的人能一直写下去而有的人却容易“中道崩殂”?我希望你在本篇文章有所收获,谢谢你的阅读!

逆向思维

我不知道你有没有试图寻找过 Vue 源码的入口,当然,这对熟悉代码审计的老手来说很容易。但是如果你并没有代码审计的任何经验,我想也你会头疼。当然,我这里并不讲如何进行代码审计。我要告诉你的是如何在不阅读源码的情况下去实现类似的功能,我称之为逆向思维

当然在你要模仿一个东西的时候你首先要熟悉它,而且还要有十分清晰的思路。下面我就谈谈我是如何用最简单的思路去实现 Vue 数据双向绑定的:

这是最简单的 Vue 代码,我相信只要是学过 Vue 都能看懂。上面的代码 new 了一个 Vue 实例,且传了一个参数(对象类型)。

所以我新建了一个文件 core.js,内容如下:

就这样,我们就有了一个基础的 Vue 类,它没有做任何事情。接下来,我们继续。替换模板里面的内容属于编译,所以我又创建了一个文件叫 compile.js(这里模拟了 Java 的思维,一个类一个文件,这样每个文件都很小巧,也很清楚每个文件是干嘛的):

还是和上面一样,我没有写任何实质性的内容,因为我始终坚持一个原则 不写无用的代码,用则写,所以我写代码的习惯是需要用到某个数据了才会把需要的数据传过来。

现在我的 Compile 需要知道从哪里开始编译,于是我们传入了第一个参数 el; 我还需要把模板内容替换成真实的数据,所以又传了第二个参数,携带数据的 vue 实例:

为了一步步的牵引思路,你会发现我在代码中习惯用 TODO 去写好下一步,当然这在你思路十分清晰的时候是没必要这样做的,除非你临时有事需要离开你的电脑桌。

编译模板

我们顺着思路继续完成 compile.js

其实,写到这里我们就已经完成了模板编译的部分。下面我们只需要在 core.js 里面调用它就好了:

先运行一下看看:

我是如何写 vue 源码的:思路篇

数据双向绑定

嗯,编译模板已经实现了,现在开始实现数据双向绑定,在这之前我希望你先去了解下设计模式之观察者模式Object.defineProperty

新建一个 Observer 类,用于数据双向绑定:

接下来就是观察者模式的实现了,基本上是一个固定的模板(我认为设计模式是很好学的东西,就好比数学公式一样):

接下来是订阅者Watcher,订阅者要做的事情就是执行某个事件:

就这样,照搬了观察者模式和利用Object.defineProperty就简单实现了一个数据双向绑定。

完整代码

下面把所有的 TODO 部分进行代码替换,我们就实现了所有的功能:

index.html

core.js

Observer.js

Compile.js

Watch.js

Dep.js

看下最终的运行图吧:

我是如何写 vue 源码的:思路篇

总结

除了基本功扎实外,写代码一定要理清思路。思路是否清晰可能决定了你能否写出一份优雅的代码,也可能决定你是否能从始至终的完成一个项目。

ultravires

发表评论

您必须才能发表评论!