vue3源码解析(一)

467 阅读2分钟

这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战

一、vue3源码架构

1、vue3初始化流程

<div id="app">
	<h1>vue3初始化流程</h1>
</div>
<script src="../../dist/vue.global.js"></script>
<script>
	const {createApp} = Vue;
	createApp({}).mount('#app');
</script>

上面的代码中createAPP是如何创建vue实例的,创建vue的实例都做了什么?我们来看看内部的执行顺序:

2、执行流程

  • createApp();创建vue实例、扩展mount方法

  • createRenderer()/baseCreateRenderer();创建renderer对象,并对外暴露三个方法:render、hydrate、createApp。其中和hydrate的实际作用是createApp返回的vue实例对象。

  • createAppAPI(render, hydrate);返回生产vue实例的createApp函数

其中render的作用给vue实例的mount方法。这时候可以看出来component()、directive()、use()、mixin()这些方法都变成了实例方法,他们也会返回实例本身,成为链式调用。并且filter被移除了

createApp({})
 .component('comp', { template: '<div>a comonent</div>' })
 .directive('focus', { mounted(el) { el.focus() } })
 .mount('#app');
  • mount(rootContainer: HostElement, isHydrate?: boolean);把createApp(rootComponent)中传⼊的根组件转换为vnode,然后渲染到宿主元素rootContainer中。

  • render(vnode, container);将vnode渲染到容器container上

  • patch(n1, n2, container);将传入的虚拟节点n1和n2进行对比,并转换成dom(初始化的时候n1是空的,所以操作之后会创建n1)

  • mount(rootContainer);执行根组件挂载,创建vnode,并把他render()出来

  • render();执行补丁函数patch();吧虚拟dom转换为真实dom

  • patch(n1, n2, container);根据n2的类型执行对应的函数,如果是根组件就会执行processComponent()方法

  • processComponent();执行组件挂载或更新,因为初始化n1是空的,所以挂载的时候会走mountComponent()

  • mountComponent();创建组件实例,执行setupComponent()设置数据状态,其中就包括setup选项的执行。

二、setup()的生效

因为vue3中可以使用composition-api,这个是写在setup()中的,下面说说它的执行过程:

1、根组件执行挂载mount()时,执行渲染函数render()获取组件的vnode,然后执行补丁函数patch()转换为真实dom,再根据组件类型判断是否走processComponent(),这里会实例化组件并处理setup选项

  • setupComponent();初始化props、slots和data

  • setupStatefulComponent(instance, isSSR);代理组件实例上下⽂,调⽤setup(),这时setup方法会收到两个参数:props和setupContext,可⽤于获取属性、插槽内容和派发事件。

  • handleSetupResult(instance, setupResult, isSSR);处理setup返回结果,如果是函数则作为组件的渲染函数,如果是对象则对其做响应化处理。

好啦这次主要说的vue3执行的过程,感谢阅读