vue 有两个阶段 分为编译时 和运行时
webpack 把vue模板编译生成对应的js代码,vue组件组件对应的template模板会被编译器转化为render函数。
运行时
编译后代码执行render函数 并返回VNode,最后将VNode 渲染成真实的DOM节点
createApp > ensureRenderer > createRenderer > baseCreateRenderer > createAppApi > mount
// overload 1: no hydration
function baseCreateRenderer<
HostNode = RendererNode,
HostElement = RendererElement
>(options: RendererOptions<HostNode, HostElement>): Renderer<HostElement>
// overload 2: with hydration
function baseCreateRenderer(
options: RendererOptions<Node, Element>,
createHydrationFns: typeof createHydrationFunctions
): HydrationRenderer
createApp 函数调用 ensureRenderer 函数 ensureRenderer 函数调用
createRenderer 函数 createRenderer 函数调用baseCreateRenderer函数
baseCreateRenderer 返回
return {
render,
hydrate,
createApp: createAppAPI(render, hydrate)
}
函数执行
- const patch = () => {} // 核心diff过程
- const processElement = () => {} // 处理element
- const mountElement = () => {} // 挂载element
- const mountChildren = () => {} // 挂载子节点
- const processFragment = () => {} // 处理fragment节点
- const processComponent = () => {} // 处理组件
- const mountComponent = () => {} // 挂载组件
- const setupRenderEffect = () => {} // 运行带副作用的render函数
- const render = () => {} // 渲染挂载流程
createAppAPI 工厂函数创建app
createAppAPI
返回的createApp
函数才是真正创建应用的入口。在createApp
里会创建vue
应用的上下文,同时初始化app
,并绑定应用上下文到app
实例上,最后返回app
。
重写mount方法
- // 创建vue应用上下文
- const context = createAppContext();
- const createApp = ((...args) => {
- // ...
- const { mount } = app; // 缓存最初的mount方法
- // 重写mount
- app.mount = (containerOrSelector) => {
- // 获取容器
- const container = normalizeContainer(containerOrSelector);
- if (!container) return;
- const component = app._component;
- // 判断如果传入的根组件不是函数&根组件没有render函数&没有template,就把容器的内容设置为根组件的template
- if (!isFunction(component) && !component.render && !component.template) {
- component.template = container.innerHTML;
- }
- // 清空容器内容
- container.innerHTML = '';
- // 执行缓存的mount方法
- const proxy = mount(container, false, container);
if (container instanceof Element) {
container.removeAttribute('v-cloak')
container.setAttribute('data-v-app', '')
}
- return proxy;
- };
- return app;
- });
重写mount 方法
完成渲染