Vue3组件初始化流程分析

本文主要来分析 vue3 组件的初始化(基于runtime-core(核心运行时)包),将从createAppmount 等常用 API 入手来分析组件的挂载、普通元素的挂载流程。

createApp

1、创建一个应用实例。使用方式如下:

import { createApp } from 'vue'
import App from './App.vue'

const rootContainer = document.querySelector("#app");
createApp(App).mount(rootContainer) 

2、内部实现:

function createRenderer(options) {...function render(vnode, container) {patch(null, vnode, container)}function patch(n1, n2, container) { ...}...return {createApp: createAppAPI(render),}
}

function createAppAPI(render) {return function createApp(rootComponent) {const vnode = createVNode(rootComponent);return {mount(rootContainer) {render(vnode, rootContainer)}};};
}

function createVNode(type, props, children) {const vnode = {type,props,children,component: null,key: props && props.key,shapeFlag: typeof type === "string" ? ShapeFlags.ELEMENT : ShapeFlags.STATEFUL_COMPONENT,el: null,};if (typeof children === "string") {vnode.shapeFlag |= ShapeFlags.TEXT_CHILDREN;} else if (Array.isArray(children)) {vnode.shapeFlag |= ShapeFlags.ARRAY_CHILDREN;}return vnode;
}

export const enum ShapeFlags { // 基于位运算确保代码运行更高效ELEMENT = 1, // 00000001 1FUNCTIONAL_COMPONENT = 1 << 1, // 00000010 2STATEFUL_COMPONENT = 1 << 2, // 00000100 4TEXT_CHILDREN = 1 << 3, ARRAY_CHILDREN = 1 << 4,SLOTS_CHILDREN = 1 << 5,TELEPORT = 1 << 6,SUSPENSE = 1 << 7,COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8,COMPONENT_KEPT_ALIVE = 1 << 9,COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT
}

const renderer = createRenderer({ // 传入dom操作相关方法,mountElement 会有说明createElement,patchProp,insert,remove,setElementText,
})



export function createApp(...args) {return renderer.createApp(...args);
} 

上述代码主要做了如下几件事:1、定义 createRenderer 函数(用来创建一个自定义渲染器,通过提供平台特定的节点创建以及更改 API,用户可以在非 DOM 环境中也享受到 Vue 核心运行时的特性)。内部定义 render 函数,createRenderer 执行完后返回一个对象。 对象键名为 createApp ,键值是通过执行 createAppAPI 函数的返回值。

2、createAppAPI 是一个高阶函数,接收 render 函数作为参数,执行会返回 createApp 函数。

3、createApp 接收根组件 rootComponent 作为参数,首先会把 rootComponent 通过 createVnode 转化成该组件对应的 Vnode,然后返回 mount 函数用来挂载应用。

4、createVnode 会创建一个 Vnode, 该 Vnode 上会有 typepropschildrenkeyel(虚拟 DOM 到真实 DOM 的映射,diff 时会用到)、shapeFlag(标识节点类型)等。注: shapeFlag 基于二进制位运算,代码运行更高效。

4、mount 接收 rootContainer 作为参数 (它可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串),执行 mount 时会执行上述传入的 render 函数, 并把组件 VnoderootContainer 作为参数传入。

5、执行 createRenderer 返回 renderer 对象,对外暴露 createApp。外界调用 createApp 时该函数内部会调用 renderer.createApp,调用 mount 时最终会调用 render 函数执行挂载流程。

render

function render(vnode, container) {...
} 

先举一个例子,假设有以下一段代码:

App.vue

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值