虚拟dom和代理可以参考其他博客,此博客介绍vue3运行流程。方便理解vue的运行流程。
一、初次渲染流程
const createApp = ((...args) => {
const app = ensureRenderer().createApp(...args);
{
injectNativeTagCheck(app);
}
const {
mount } = app;
app.mount = (containerOrSelector) => {
const container = normalizeContainer(containerOrSelector);
if (!container)
return;
const component = app._component;
if (!isFunction(component) && !component.render && !component.template) {
component.template = container.innerHTML;
}
// clear content before mounting
container.innerHTML = '';
const proxy = mount(container);
container.removeAttribute('v-cloak');
container.setAttribute('data-v-app', '');
return proxy;
};
return app;
});
ensureRenderer:创建render函数
return {
render,
hydrate,
createApp: createAppAPI(render, hydrate)
};
createAppAPI 返回createApp函数;
createApp创建了app对象。app对象有mount方法。
mount 调用render方法,render调用patch方法,patch方法判断shapeFlag & 6 /* COMPONENT */,执行processComponent方法,此时还没有生产虚拟dom。
processComponent判断首次渲染执行mountComponent。
mountComponent创造instance对象,先执行setupComponent方法,setupComponent主要作用就是生产各种属性和方法,例如props、render、type等;setupComponent执行setupStatefulComponent方法,在setupStatefulComponent里finishComponentSetup方法执行compile方法,编译出render方法,render是instance对象一个属性,rende方法可以编译出虚拟dom。
"const _Vue = Vue
const {
createVNode: _createVNode, createTextVNode: _createTextVNode } = _Vue
const _hoisted_1 = /*#__PURE__*/_createVNode("h1", null, "Latest Vue.js Commits", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createTextVNode(" - ")
const _hoisted_3 = {
class: "message" }
const _hoisted_4 = /*#__PURE__*/_createVNode("br", null, null, -1 /* HOISTED */)
const _hoisted_5 = /*#__PURE__*/_createTextVNode(" by ")
const _hoisted_6 = {
class: "author" }
const _hoisted_7 = /*#__PURE__*/_createTextVNode(" at ")
const _hoisted_8 = {
class: "date" }
return function render(_ctx, _cache) {
with (_ctx) {
const {
createVNode: _createVNode, renderList: _renderList, Fragment: _Fragment, openBlock: _openBlock, createBlock: _createBlock, vModelRadio: _vModelRadio, withDirectives: _withDirectives, toDisplayString: _toDisplayString, createTextVNode: _createTextVNode } = _Vue
return (_openBlock(), _createBlock(_Fragment, null, [
_hoisted_1,
(_openBlock(true), _createBlock(_Fragment, null, _renderList(branches, (branch) => {
return (_openBlock(), _createBlock(_Fragment, null, [
_withDirectives(_createVNode("input", {
type: "radio",
id: branch,
value: branch,
name: "branch",
"onUpdate:modelValue": $event => (currentBranch = $event)
}, null, 8 /* PROPS */, ["id", "value", "onUpdate:modelValue"]), [
[_vModelRadio, currentBranch]
]),
_createVNode("label", {
for: branch }, _toDisplayString(branch), 9 /* TEXT, PROPS */, ["for"])
], 64 /* STABLE_FRAGMENT */))
})