# vue3 源码 start

# The basic

# 目录

├── packages                  // Vue源代码目录
├── scripts
├── test-dts                  // TypeScript 声明文件
├── .prettierrc               // 代码格式化 prettier 的配置文件
├── api-extractor.json        // TypeScript 的API提取和分析工具
├── CHANGELOG.md              // 更新日志
├── jest.config.js            //  测试框架 jest 的配置文件
├── LICENSE
├── README.md
├── rollup.config.js          // 模块打包器 rollup 的配置文件
├── tsconfig.json             // TypeScript 配置文件

# packages

├── compiler-core            // 核心,抽象语法树和渲染桥接实现
├── compiler-dom             // Dom的实现
├── compiler-sfc             // Vue单文件组件(.vue)的实现
├── compiler-ssr
├── reactivity
├── ref-transform
├── runtime-core
├── runtime-dom
├── runtime-test
├── server-renderer         // 服务端渲染实现
├── sfc-playground
├── shared                  // package 之间共享的工具库
├── size-check
├── template-explorer
└── vue
└── vue-compat
├── global.d.ts

# p:runtime-dom

  • 根的写法, vue3和vue2不一样
import { h, createApp } from '@vue/runtime-dom'

const RootComponent = {
  render() {
    return h('div', 'hello world')
  }
} // #0
createApp(RootComponent).mount('#app')
  • It's renderer (渲染器)

# createApp() #0

  • packages\runtime-dom\src\index.ts
export const createApp = ((...args) => {
                  // #1
  const app = ensureRenderer().createApp(...args) 
    ...
  const { mount } = app
  app.mount = (containerOrSelector: Element | ShadowRoot | string): any => {
    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, false, container instanceof SVGElement)
    if (container instanceof Element) {
      container.removeAttribute('v-cloak')
      container.setAttribute('data-v-app', '')
    }
    return proxy
  }

  return app
}) as CreateAppFunction<Element>

# ensureRenderer() #1

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

# rendererOptions #2

const rendererOptions = extend({ patchProp  //处理 props 属性 
}, nodeOps // 处理 DOM 节点操作
)

# f:renderer.ts

  • packages\runtime-core\src\renderer.ts

# createRenderer(<..>) #3

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

# baseCreateRenderer<..>() #4

function baseCreateRenderer(
  options: RendererOptions,
  createHydrationFns?: typeof createHydrationFunctions
): any {
  const {
   ... 
  } = options

  // ....此处省略两千行,我们先不管

  return {
    render,
    hydrate,    //  #5
    createApp: createAppAPI(render, hydrate)
  }
}

# createAppAPI #5

  • following in previous, aren't they familiar methods?
export function createAppAPI<HostElement>(
  render: RootRenderFunction,
  hydrate?: RootHydrateFunction
): CreateAppFunction<HostElement> {

  return function createApp(rootComponent, rootProps = null) {
    ...

    // yiki: default app cofig
                      // #6
    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) {...},
      use(plugin: Plugin, ...options: any[]) {...},
      mixin(mixin: ComponentOptions) {..},
      component(name: string, component?: Component): any {...},
      directive(name: string, directive?: Directive) {...},
      mount(...},
      unmount() {...},
      provide(key, value) {...}
    })
      ...
    return app
  }
}

# createAppContext() #6

export function createAppContext(): AppContext {
  return {
    app: null as any,
    config: {
      isNativeTag: NO,
      performance: false,
      globalProperties: {},
      optionMergeStrategies: {},
      errorHandler: undefined,
      warnHandler: undefined,
      compilerOptions: {}
    },
    mixins: [],
    components: {},
    directives: {},
    provides: Object.create(null),
    optionsCache: new WeakMap(),
    propsCache: new WeakMap(),
    emitsCache: new WeakMap()
  }
}
Last Updated: 2021/12/1 下午4:04:24