前言
相信大家在前端从业生涯中都会被问到过,有了解过Vue源码吗?我是没有的,所以今天就来读好吧,浅浅读一下,顺便记录一下。
那究竟怎么读,从哪里读,我就不啰嗦了,直接给大家一个链接,这篇文章给了大家一个方向,可以理解为项目前期的环境部署吧
如何调试Vue3源码? - CherishTheYouth - 博客园 (cnblogs.com)
那岂不是,直接看这里就好了?没必要把文章写下去了?当然不是,下面,我将根据文章给的exmaple页面(todomvc.html),一步一步调试,揭开Vue的奥秘!
开始
因为Vue项目太大了,我觉得直接硬着头皮看有点太干了,也看不懂,变量引用来引用去的,还全是英文,真的很难,除非是看视频,但是我看了几个视频,也是东一处西一处的,那只能自己调试领悟的才更深刻
Debugger
开局映入眼帘的就是一个经典的ES6对象解构,写过vue的朋友应该都用过这些方法,那我们现在的目的就是了解他们的底层
因此直接一手debugger,然后交给浏览器
然后,我们跟着调试,点击步骤(F9),右侧还能清晰的看到当前debugger到的作用于的变量值
1. createApp
连续点击了几个步骤,来到了createApp,很熟悉,这里是创建vue的地方
我们继续往下
来到这里,要加个debugger,不然一下就跳过去了,浏览器给我跳到了另一个文件(packages/runtime-dom/src/index.ts)
再继续往下
1. ensureRenderer
来到一个ensureRenderer()的方法,根据上一张图片以及这张图片,我们能推断出,这个方法会返回一个对象,然后这个对象再继续调用createApp的方法
const app = ensureRenderer().createApp(...args)
然后捏 vue啥也不说,直接return一个renderder出来
// 此部分代码和上一张调试的图片一样
const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps)
// lazy create the renderer - this makes core renderer logic tree-shakable
// in case the user only imports reactivity utilities from Vue.
let renderer: Renderer<Element | ShadowRoot> | HydrationRenderer
let enabledHydration = false
function ensureRenderer() {
// eslint-disable-next-line no-console
console.log(rendererOptions)
return (
renderer ||
(renderer = createRenderer<Node, Element | ShadowRoot>(rendererOptions))
)
}
那么,在初始阶段,renderer只是声明了,但是并未赋值,所以是undefiend,那么必然会执行createRedenrer()这个方法,并重新赋值给renderer
1. createRedenrer
【rendererOptions】
这里还给了个rendererOptions的参数,我不知道他是哪里来的,很好奇,就加了个打印
但其实,我们也能从上面的代码看到,rendererOptions是这里声明的
const rendererOptions = /*#__PURE__*/ extend({ patchProp }, nodeOps)
好啊好啊,extend的又是啥,patchProp又是啥,nodeOps又又是啥
【rendererOptions】 extend
直接ctrl+点击,我们找到了这个位于shared/general.ts下的extend,好家伙,原来他就是Object.assign,只是换了个名字,一般我们会在浅拷贝这里用到这个方法
【rendererOptions】 patchProp、nodeOps
这俩兄弟都是直接引入的,patchProp是一个方法,nodeOps是个对象,有一大堆属性和方法
那么,结合控制台以及extend的乔装术,我可以推断,rendererOptions就是把patchProps和nodeOps的属性及方法融合到一起了,可以进入下一关!
2. baseCreateRenderer
createRenderer来自于packages/runtime-core/src/renderer.ts,莫非他就是负责渲染工作的,失敬失敬,只见他又要调用别的方法,这一瞬间,我慌了神!
在同个文件夹下,我找到了这个方法,小小折叠了一下代码,千百来行,可以看出这是一个很多代码的方法
看一下这个方法的return,有createApp,在方法里是叫createAppAPI,我们前面打断点的地方就是需要这个返回值才能进行下一步的操作,因此,这个baseCreateRenderer我愿封他为神
这个方法里面还有许多的内部方法,也就是八股文经常问的闭包,失敬失敬,我看这篇文章就先到这里收尾,下篇文章在来着重看看这个baseCreateRenderer方法!