【vue3源码】十一、初始vue3中的渲染器

【vue3源码】十一、初始vue3中的渲染器

在介绍渲染器之前。我们先简单了解下渲染器的作用是什么。

渲染器最主要的任务就是将虚拟DOM渲染成真实的DOM对象到对应的平台上,这里的平台可以是浏览器DOM平台,也可以是其他诸如canvas的一些平台。总之vue3的渲染器提供了跨平台的能力。

渲染器的生成

当使用createApp创建应用实例时,会首先调用一个ensureRenderer方法。

export const createApp = ((...args) => {
   
   
  const app = ensureRenderer().createApp(...args)
  // ...
  
  return app
}) as CreateAppFunction<Element>

ensureRenderer函数会返回一个渲染器renderer,这个renderer是个全局变量,如果不存在,会使用createRenderer方法进行创建,并将创建好的renderer赋值给这个全局变量。

function ensureRenderer() {
   
   
  return (
    renderer ||
    (renderer = createRenderer<Node, Element | ShadowRoot>(rendererOptions))
  )
}

createRenderer函数接收一个options参数,至于这个options中是什么,这里我们暂且先不深究。createRenderer函数中会调用baseCreateRenderer函数,并返回其结果。

export function createRenderer<
  HostNode = RendererNode,
  HostElement = RendererElement
>(options: RendererOptions<HostNode, HostElement>) {
   
   
  return baseCreateRenderer<HostNode, HostElement>(options)
}

至此,我们就找到了真正创建渲染器的方法baseCreateRenderer。当我们找到baseCreateRenderer的具体实现,你会发现这个函数是十分长的,单baseCreateRenderer这一个函数就占据了2044行代码,其中更是声明了30+个函数。

在此我们先不用关心这些函数的作用,在后续介绍组件加载及更新过程时,你会慢慢了解这些函数。

接下来我们继续看渲染器对象的结构。

渲染器

return {
   
   
  render,
  hydrate,
  createApp: createAppAPI(render, hydrate)
}

baseCreateRenderer最后返回了一个对象,这个对象包含了三个属性:render(渲染函数)、hydrate(同构渲染)、createApp。这里的createApp是不是很熟悉,在createApp中调用ensureRenderer方法后面会紧跟着调用了createApp函数:

export const createApp = ((...args) => {
   
   
  const app = ensureRenderer().createApp(...args)
  // ...
  
  return app
}) as CreateAppFunction<Element>

注意这里不要两个createApp混淆了。渲染器中的createApp并不是我们平时使用到的createApp。当我们调用createApp方法进行创建实例时,会调用渲染器中的createApp生成app实例。

接下来我们来看下渲染器中的createApp。首先createApp方法通过一个createAppAPI方法生成,这个方法接收渲染器中的renderhydrate

export function createAppAPI<HostElement>(
  render: RootRenderFunction,
  hydrate?: RootHydrateFunction
): CreateAppFunction<HostElement> {
   
   
  return function createApp(rootComponent, rootProps = null) {
   
   
    // ...
  }
}

createAppAPI函数会返回一个闭包函数createApp。这个createApp就是通过ensureRenderer().createApp(...args)调用的方法了。接下来看createApp的具体实现:

createApp完整代码
function createApp(rootComponent, rootProps = null) {
   
   
  if (!isFunction(rootComponent)) {
   
   
    rootComponent = {
   
    ...rootComponent }
  }

  if (rootProps != null && !isObject(rootProps)) {
   
   
    __DEV__ && warn(`root props passed to app.mount() must be an object.`)
    rootProps = null
  }

  const context = createAppContext()
  const installedPlugins = new Set()

  let isMounted = false

  const app: App = (context.app = {
   
   
    _uid: uid++,
    _component: rootComponent as ConcreteComponent,
    _props: rootProps,
    _container: null,
    _context: context,
    _instance: null,

    version,

    get config() {
   
   
      return context.config
    },

    set config(v) {
   
   
      if (__DEV__) {
   
   
        warn(
          `app.config cannot be replaced. Modify individual options instead.`
        )
      }
    },

    use(plugin: Plugin, ...options: any[]) {
   
   
      if (installedPlugins.has(plugin)) {
   
   
        __DEV__ && warn(`Plugin has already been applied to target app.`)
      } else if (plugin && isFunction(plugin.install)) {
   
   
        installedPlugins.add(plugin)
        plugin.install(app, ...options)
      } else if (isFunction(plugin)) {
   
   
        installedPlugins.add(plugin)
        plugin(app, ...options)
      } else 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MAXLZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值