SoFunction
Updated on 2025-04-07

How to call a function in Vue3 initialization

Vue3 initialization call function

createApp({}).mount(‘#app')

Entry file runtime-dom/src/

  • createApp -> createRenderer -> createBaseRenderer (The render function and a series of rendering functions are also created here) -> createAppAPI (returns the real createApp method), returns the instance app,
  • Then ("#app") -> createVNode -> render(vnode,rootcontainier,isSVG) -> patch -> processComponent -> mountComponent (first rendering) or updateComponent ->(createComponentInstance , setupComponent, setupRenderEffect)
  • For setupComponent, there are setup functions and no setup functions to process the case. If there is one, go to the setup function to process. Initialize props, etc., and call setup, setupComponent->finishComponentSetup (the initialization of the version of options will be processed here).
  • For setupRenderEffect, a series of life hook functions are executed, a rendering ReactiveEffect is created, and the **()** method is executed

ReactiveEffect

Similar to Watcher, computered, watch, componentUpdateFn also uses ReactiveEffect during rendering,

const effect = new ReactiveEffect(fn,…), except for the calculation attribute that will call()->fn() when it is accessed, access the responsive variables in fn to collect dependencies. The other setupRenderEffect, watch, watchEffect, will call() to collect dependencies after creating ReactiveEffect, where

  • setupRenderEffectResponse variables that depend on
  • watch(source,cb,options), will execute the function that accesses the source and collect dependencies
  • watchEffect(fn), will automatically perform fn collection dependencies
  • effect(fn,options),The options have a lazy:true option, which means that the fn function is not executed immediately to collect dependencies, returns a run function, calls run() again, executes the fn function once, and collects dependencies
// 1. Calculate properties// 
// The ComputedRefImpl class constructor calls new ReactiveEffect = new ReactiveEffect(getter, () => {
      if (!this._dirty) {
        this._dirty = true
        triggerRefValue(this)
      }
    })
    
// 2. effect
// 
// In the effect function, the second parameter effect(fn,{lazy:true}) can be received, indicating that it will not be executed immediately  const _effect = new ReactiveEffect(fn)
// 3. doWatch method// watch and watchEffect are both used through doWatch function, where new ReactiveEffect is called, and then () is executed according to different situations. For watchEffect, it is //executor callback, for watch, it is to access the listening data, and then collect dependencies  const effect = new ReactiveEffect(getter, scheduler)
// 4. 
//In setupRenderEffectconst effect = ( = new ReactiveEffect(
      componentUpdateFn,//Update component functions      () => queueJob(update),
       // track it in component's effect scope
    ))

Vue3 program initialization process

initialization

In vue3, the program initialization no longer follows vue2's new Vue() method, but uses createApp. What's happening in createApp?

Reason for rewriting

createApp is a factory function in Vue that is imported and called in the form of a function. And the benefit of functional is

1. Eliminate the static method originally mounted on Vue and becomes an instance method, which can reduce memory usage, facilitate tree-shaking, and reduce packaging volume;

2. Because the functional and class decorator support ts well, calling them using functions can better support ts and improve type support.

3. The root component's API, such as data, must maintain the same format as the subcomponent's API, and change the mount from $mount to mount, simplifying the API and unifying the consistency of the API.

4. The method of mounting in new Vue will cause global pollution and cannot be independent. CreateApps can be independent of each other and mounted on demand.

Process implementation

mount

const Vue = {
	createApp(options) {
		//Return to the app instance		return {
			mount(selector){
				// Get the rendering function and compile the result				// Render the dom and append it to the host element			}
			compile(template){
			//Return to render				return function render(){
					//Description view				}
			}
		}
	}
}

When calling createApp, if there is no render in options, the component is initialized, and the compile is called to generate a render. If there is a render, it will be mounted directly;

In Vue2, append elements are compared and replaced, and the differences between diff elements are compared and judged. In Vue3, delete and re-add them directly.

Responsive variables can be defined in setup or data, and the setup has higher priority.

createApp

The two initialized functions exposed by Vue, createApp and createRenderer, the call relationship between them

/*CreateApp exposed to Vue*/
function createApp(options){
    const renderer =  ({
        /*Define some platform-specific APIs, some instances*/
        aaa(){},
        bbb(){}
    })
    /*The createApp called by the user is actually the createApp of the renderer*/
    return ()
}
function createRenderer({aaa,bbb}){
    /*Get the renderer*/
    /*This createApp is inside the function*/
    return createApp(options){
        /*mount logic*/
        return {
            /*Return App instance*/
        }
    }
}

Source code process

1. The user calls the createApp method =》Get the renderer through ensureRenderer

2. The renderer calls createRender =》※Calculating the factory function baseGreateRenderer, which defines patch and diff, and finally returns a render to render the spa page, a hydrate to inject water into the ssr page, and a function createApp (different from Vue's createApp)

3. In the createApp of the function, the program instance method will be defined, such as mount, get, set, use, mixin, etc.

4. The mount instance method will check whether there is a root component mounted and what method to use to mount (spa/ssr)

5. The render method calls the patch method for patching

6. The patch method judges the mount method based on the type of incoming node. If it is mounted for the first time, it is a mount component, followed by the mount element (the patch method will convert vnode into node node)

7. The patch method executes the internal processComponent method and finally executes the mountComponent method, which is the method of the final execution of $mount in Vue2.

Initialization process

1. Instantiation of the root component: call createComponentInstance

2. Initialize the root component: call the setupComponent method, which is the this.$_init method in Vue2, to merge the options and set hooks and responsiveness.

3. Side effect function of installing render function: setupRendererEffect

In Vue3, the watcher is cancelled and changed to a side effect function. The side effect function will be re-executed every time the responsive data changes. The execution of the internal render function will trigger dependency collection, so that when the responsive data changes, the responsive component will be updated.

PS: The difference from useEffect in react is that useEffect needs to manually collect dependencies, while effect() in Vue will automatically collect dependencies.

The above is personal experience. I hope you can give you a reference and I hope you can support me more.