一、为什么是amd?
首先并不是一定要用amd,只是在这里考虑到以下几个方面,而amd都能满足这些需求,所以用了amd。
1. 为了按需加载:页面模板、页面依赖的自定义组件模板、页面依赖的wxs,这些编译后的模块需要按需加载,
例如A页面渲染的时候,webview中不会去加载B页面的模板内容,A页面所依赖的模块,
都会通过异步的方式加载到内存中,最终的modDefine第二个参数会是一个数组,
数组里面放的是依赖的模块ID;
当然目前在我们的课程中并没有涉及到自定义组件、wxs这些内容,
所以就暂时只把页面转化成了amd模块(没有任何依赖),并且为了降低静态资源加载的复杂性,
暂时没去做异步加载这个事情,就干脆把所有的amd都打包到一起了;
其实如果是渲染首页,是没必要加载详情页的模板资源的,属于资源浪费,
这部分计划的是后续在高阶部分内容去优化,目前先打个基础在这里,后面慢慢做改造;
2. 为了给每个模块分配单独的作用域:特别是以后要讲的wxs,避免逻辑冲突;
3. 微信用了amd,跟着最佳实践走;
以上是为什么选择amd,当然技术手段是开放性的,不一定非要用amd,
也可以在编译的时候去分析页面依赖的资源情况,按照页面维度拆分文件也可以,
每个webview去加载指定的资源即可但要注意的是,不管你通过什么样的方式来实现,请确保每个模块的作用域一定要隔离开;
二、usingComponents
你的思路是正确的,usingComponents的结构大概如下:
usingComponents: {
[组件名称]: [模块路径]
}
在编译的时候,会根据json中usingComponents配置,来组织模块之间的依赖情况,从而在资源加载过程中
把依赖的模块信息全部加载到内存中;后续在创建vue树的树的时候,可以根据页面、
自定义组件中的usingComponents信息,
找到对应的模块资源信息,拿到了资源信息也就拿到了render函数;
以上全部是文字描述,听着可能有点绕,课程结束后,你可以顺着我的思路自己尝试做下自定义组件扩展,
另外还有一点需要注意下,在小程序架构中,页面、自定义组件有两种形态:
1. 静态资源:这个是唯一的,需要通过资源路径来关联,例如模板编译产物、js编译产物
2. 运行时对象:对于页面来讲是唯一的,但对于自定义组件来讲,可能会有多个,
例如你封装了一个自定义按钮组件,代码资源永远只有一份;但最终在运行时,
可能会实例化多个按钮对象(因为你可能会在模板中写入多个按钮标签),UI线程每个按钮对象实例化的时候,
都会在逻辑线程创建一个映射实例(渲染线程在创建组件的时候,生成一个id,发送到逻辑线程来映射),
每个线程
都有一个映射表;有了映射,后面才能做组件维度的精准更新,例如你改变了A按钮的状态,
不可能把ui线程所有按钮的状态都改变吧?
在我们现在的课程中,目前只涉及到page的映射,还比较初级,后面把自定义组件加进来就复杂多了;
上面提到的运行时对象映射就很有意思,在dom api中: 我们在js中执行,document.getElementById();
其实就是创建了一个浏览器渲染线程dom对象在js环境中的映射对象,它只是dom对象的一个js描述,
不是一个真正的dom对象,你每次对这个js对象的操作,其实底层都是在做跨线程通信,
其实浏览器环境也分渲染线程和js线程,只是浏览器在执行js的时候,会暂停渲染线程,
让我们错觉它是单线程;
感觉扯了些题外话,可以尝试理解,不明白的我们再交流,祝学习愉快!