笔者自己写了一个 vue3 的简易版实现,非常简易,没有阅读难度,起名 beggar-vue
,意思不是 “乞丐版 vue”,而是 “乞丐看了都可怜的 vue”。虽然实现很粗糙,但实现原理方面基本完全贴合源码,少量不同的地方都会做出标注和提醒,源码传送门在这里 beggar-vue,以下是一些参考信息
References:
vue-next: vue3 源码,很值得看
vue-design: 一个大佬,vue 贡献者写的剖析 vue 设计原理的博客,很值得看
mini-vue: 另一个大佬写的 mini-vue,有详细的注释,很值得看
说实在的,vue 作为我第一个且是目前唯一一个上手的框架是相当有情怀,有很多问题从我第一次创建 vm 实例对象就出现了,比如 vue 到底是什么,我创建的 new Vue
又是什么东西,为什么写个 v-model
就可以实现所谓的 “双向数据绑定” 等等
而对于我这个笨比来说,拜读他人的博客或观看视频教程给我的体会都不够直接,我更希望能自己实现一遍,这样我自己的思路会是连贯的,也能总结出自己的理解,作为一个初入前端圈子的小白,这些对我来说都非常非常重要
因此就下定决心自己尝试手写一个 vue 简易版的实现,过程大概耗时一个月,查阅了各种资料就这样写完了
始终坚持 “功能先上,能跑就行”,因此跑是大概能跑了,但是存在 bug 是必然也是肯定的,不过这些倒也不太重要,以下是我之前文中出现过的截图
<div id="app">
<div>
<p class="a">hello Beggar Vuep>
<div>counter: {{ counter.value }}div>
<button @click="add">clickbutton>
div>
div>
<script>
createApp({
setup() {
const counter = ref(0);
const add = () => counter.value++;
return {
counter,
add,
};
},
}).mount('#app');
script>
随便给 p.a
写个样式
.a {
font-size: large;
}
也不是做了什么了不起的事情,不谈个人感受,关注点放到 beggar-vue 本身
写完之后越发觉得写一个优秀的开源真的非常难,需要考虑的事情太多了,源码中大量代码是在进行容错处理以及环境判断,还有大量的 issues 修改痕迹,都有注释
vue 整体的项目架构非常有意思,老实说我是开了眼了,各个模块分开打包,我只实现了核心模块,除此之外其实还有很多,比如说给 sfc
、ssr
提供支持的模块,浏览器环境的支持模块等等。模块之间分开打包的一个好处就是模块之间的耦合度低,可以直接复用其中的某个模块进行二次开发,目前按照我的了解有 uniapp、weex、mpvue 等,这些都是基于 vue 的核心模块开发出来的框架
vue 的代码组织对我来说当然是非常值得学习的,在兼顾了鲁棒性的同时,也有着优秀的可扩展性可维护性,但是说老实话,vue 的源码并没有想象中那么晦涩难懂,根本没有出现面试题里面那些反人类代码,甚至都没有出现什么奇怪的技巧,硬要说的话大概就是偶尔用用函数柯里化来做函数缓存,用用位图来做类型标记,当然肯定有我没注意到的操作。但就目前我看过的源码而言,最起码代码本身我是看得懂的。代码量也没有想象中的大,也可能是因为我偷了大懒
你可能会想,你再凡尔赛一个我看看?怎么可能不难??
阅读源码最大的困难乃至阅读别人(脑血栓 coder 除外)的代码最大的困难其实并不在于看不懂代码,最大的难点应该是如下三点:
newIndexToOldIndexMap
和 maxNewIndexSoFar
,这两个就是 diff 算法中最关键的变量,能搞清楚他们是什么东西在做什么事情,基本就能搞明白 diff 算法。最后是一些个人建议,针对源码阅读以及我的这几篇博客
关于源码阅读
关于我的博客
最后一点提醒大家对别人的博客留个心眼,说不定有写错的地方,我踩过坑