前言
上篇我们见到一个很厉害的方法,这篇我们来看看
baseCreateRenderer
首先,方法太多了,我也不一个一个数有多少个了,因为我们着重使用createApp方法,那么我们就跟着代码走,用到哪个方法就分析哪个方法
1. 方法重载
上篇漏看了个东西,这里有个ts的函数重载
就是他可以接受不同类型,数量的参数,但是这些重载只是声明了不同参数的类型,数量,但不具体实现,只有最下边那个2000多行的要实现,并且要对所有重载都有具体的实现,我也是半桶水,大家懂的可以评论区补充,这里我就不误人子弟了哈哈
2. createApp: createAppAPI(render, hydrate)
上篇我们看到Return里面有返回createApp方法,这里我们直接来看看
createAppAPI很着急,直接就是调用了起来,那必然 CreateAPP是createAPPAPI方法的return,render和hydrate作为参数传入,那我们也要看看他俩是个啥
1. render
render是个小小方法,由于暂时没有调用到,这里不做具体分析,因为暂时没有太多信息能让我看懂这个方法,所以先不纠结
2. hydrate
hydrate是个变量,他的类型是一个方法,完了还带个[0],没看懂
这里也不纠结,继续往下走
3. createAppAPI
createAppAPI在另一个文件packages/runtime-core/src/apiCreateApp.ts
而且他貌似也不干活,他return了一个createApp方法出来
那就是,如果要程序继续下去,这个方法得调用它,我们回顾到上一篇的createApp,仔细一看,是有调用的!还给了参数
那就就可以继续往下走
createApp
到这里有点懵,那两个参数rootComponent, rootProps是哪里提供的,来打个断点看看
经过我一波调试+打印,原来rootComponent就是我们在html的配置
好,既然都已经用到这些参数了,那就说明事情已经逐步进入正轨啊哈哈哈
接着上上张图,我们看到有个叫做!isFunction的判断,isFunction的代码在此
export const isFunction = (val: unknown): val is Function =>
typeof val === 'function'
那我们传入的参数是个obj,显然不是个方法,因此会进入这个if
这里就是,如果是个对象,就需要对传入的对象进行一个浅拷贝,妙蛙,那在这个方法内对rootComponent下的所有属性进行操作时,都不会影响到用户的初始配置,但是引用类型还是会有影响,毕竟不是深拷贝,目前只能这么推断,只能继续往下看
接下来是一个if判断,rootProps != null 并且 rootProps不是一个对象,就会进入这个if,但这里我们的rootProps是null,因此不会进入
再往下,是一些赋值操作
再再往下,给app给了个方法,然后有个__CPMPAT__变量,我在这个页面没找到,但是全局很多地方都有,在dev.js和config都能看见,输出结果是false,所以没有进入这个if
接着,我在全局搜索了这个变量,在许多地方都用了这个变量,但是基本上就是找不到在哪里定义的,直到在一个dev.js的文件找到了
我尝试修改他的值,再重新打包调试,发现__COMPAT__的值会因为这里的修改而发生改变,因此只能暂定是这里定义的,然后不深究,继续往下调试
接着,createApp返回了一个app变量,也就是在上面的那个app,这里再回顾一下,因为刚才没细看
可以看出很多熟悉的方法:use、mixin、component、directive、mout、onUnmout、unmount...
接着,又返回到index.ts这里了,我们的app终于获取到值了,真是山路十八弯啊,太曲折了
这里可以简单概括下,因为有点跳
[createApp] (todomvc.html) ↓
[createApp] (index.ts) ↓ ←
[ensureRenderer] (index.ts) ↓ ↖
[createRenderer] (renderer.ts) ↓ ↑
[baseCreateRenderer] (renderer.ts) ↓ ↑
[createAppAPI] (apiCreateApp.ts) ↓ ↑
[createApp] (apiCreateApp.ts) → ↑
目前,跟着调试走的话,baseCreateRenderer方法就只能解释到这里了