CreateApp position

vue/src/index.ts => runtime-dom => createApp

// vue/src/index.ts

export { compileToFunction as compile }
export * from '@vue/runtime-dom'
Copy the code
// runtime-dom/src/index.ts
import {
  createRenderer,
  createHydrationRenderer,
  warn,
  RootRenderFunction,
  CreateAppFunction,
  Renderer,
  HydrationRenderer,
  App,
  RootHydrateFunction,
  isRuntimeOnly,
  DeprecationTypes,
  compatUtils
} from '@vue/runtime-core'

export const createApp = ((. args) = > {
  constapp = ensureRenderer().createApp(... args) ...return app
}
Copy the code

Looking for the state

ensureRenderer() => return createRenderer() => return baseCreateRenderer() =>

return {
    render,
    hydrate,
    createApp: createAppAPI(render, hydrate)
  }
Copy the code

=> createAppAPI()

A print

app instance

State is exposed as an instance returned by mount, unlike VUe2. App status where data is a Function (Function only) is not yet running exposed.

mount

// mount
const vnode = createVNode(
    rootComponent as ConcreteComponent,
    rootProps
  )
vnode.appContext = context

render(vnode, rootContainer, isSVG)

isMounted = true
app._container = rootContainer

returngetExposeProxy(vnode.component!) || vnode.component! .proxy// Return vnode.component! .proxy
Copy the code

PublicInstanceProxyHandlers

Directly see the proxy handler, find packages \ runtime – core \ SRC \ componentPublicInstance ts

export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
    get({ _: instance }: ComponentRenderContext, key: string){... }, set({_: instance }: ComponentRenderContext, key: string.value: any) :boolean{... },has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions }}: ComponentRenderContext, key: string){... }}Copy the code

Trying to back

Back to the first version, v3.0.0-alpha.0

From Readme to Contributing Guide

Development Setup

$ yarn # install the dependencies of the project
Copy the code

A high level overview of tools used:

  • TypeScript as the development language
  • Rollup for bundling
  • Jest for unit testing
  • Prettier for code formatting

Oho, NPM run dev error compiler-SSR package.json file not found There may be some problems, it is still a jump version of v3.0.0-alpha.1, still error. The direct v3.0.0

// There is always an error here
const pkg = require(`.. /packages/${f}/package.json`)
// Why is Utah ok? Is it the Node version problem?
Copy the code

Forget it. Let’s move on to V3.2.20

createApp

// packages\runtime-dom\src\index.ts
export const createApp = ((. args) = > {
  constapp = ensureRenderer().createApp(... args) app.mount = (containerOrSelector: Element | ShadowRoot |string) :any= > {
    const container = normalizeContainer(containerOrSelector)
    if(! container)return

    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
}
Copy the code

createVNode

// packages\runtime-core\src\apiCreateApp.ts
// createAppAPI() => return createApp()
mount() {
  const vnode = createVNode(rootComponent)
  returnvnode.component! .proxy }Copy the code
// packages\runtime-core\src\vnode.ts

// Determine the entry
export const createVNode = (
  __DEV__ ? createVNodeWithArgsTransform : _createVNode
) as typeof _createVNode

// Intercept, adjust parameters, and finally pass createBaseVNode
function _createVNode(
  type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT,
  props: (Data & VNodeProps) | null = null,
  children: unknown = null,
  patchFlag: number = 0,
  dynamicProps: string[] | null = null,
  isBlockNode = false
) :VNode{
    if (!type || type=== NULL_DYNAMIC_COMPONENT){... }if (isVNode(type)) {... }if (isClassComponent(type)) {}
    
    return createBaseVNode(
        type,
        props,
        children,
        patchFlag,
        dynamicProps,
        shapeFlag,
        isBlockNode,
        true)}Copy the code

render

Initialize vNode with no Component and enter render with Type

//packages\runtime-core\src\renderer.ts
const render: RootRenderFunction = (vnode, container, isSVG) = > {
    patch(container._vnode || null, vnode, container, null.null.null, isSVG)
    flushPostFlushCbs()
    container._vnode = vnode
}
Copy the code

patch

patch => processComponent => mountComponent => setupRenderEffect

// packages\runtime-core\src\renderer.ts
const effect = new ReactiveEffect(
      componentUpdateFn,
      () = > queueJob(instance.update),
      instance.scope // track it in component's effect scope
    )
Copy the code
// packages\reactivity\src\effect.ts
export class ReactiveEffect<T = any> {
active = true
  deps: Dep[] = []

  // can be attached after creationcomputed? :booleanallowRecurse? :booleanonStop? :() = > void
  
  constructor(
    public fn: () => T,
    public scheduler: EffectScheduler | null = null, scope? : EffectScope |null
  ) {
    recordEffectScope(this, scope)
  }
  
  run() {}
  stop(){}}Copy the code

effect

Finally, the function componentUpdateFn is passed to Effect to enter the track loop