To save time, this article will not show too much code, but only a portion of the source code that needs to be understood.

Process overview of New Vue

When executing new Vue to instantiate a Vue object, the main flow can be roughly divided into the following parts:

  • Init: initializes, merges options and mounts properties for the current instance
  • $mount: Processes the mount data, generates the render function, and finally triggers the execution of the page mount method
  • Render: Render virtual DOM(vnode)
  • Patch: The stage of drawing the virtual DOM to the page, including the difference comparison of the virtual DOM.

That’s a lot to cover, so in two parts, let’s take a look at what the init and $mount phases do.

init

Have an article on the understanding to the position of the Vue constructor defined as/instance/SRC/core index, js, when performing the new Vue performed when the constructor, the constructor is called _init method, therefore, this stage is mainly to explore the _init method did what?

_init method

_init method execution flow

_init methods defined in SRC/core/instance/init. Js. When you find the method defined by _init, here’s what you should probably do from top to bottom (ignoring things that aren’t relevant to the main line, such as performance burying points) :

  1. Saves the current instance object to the VM variable.

  2. Bind the _uid attribute to the current instance VM, which uniquely identifies the current instance.

  3. Bind the _isVue attribute to the current instance VM, which identifies the current instance as a Vue instance. I understand that this attribute is intended to distinguish it from component instances.

  4. Call initInternalComponent to check if options exist and options._isComponent is true. This step is optimized for internal component instantiation. The new Vue we are exploring here does not go into this logical branch, but into the else logical branch, where the mergeOptions method is first called to merge some options and bind the merged options to the $options property of the current instance VM

  5. Determine if the current environment is a production environment, bind the _renderProxy attribute to the current instance VM and assign the instance itself. In a development environment, you need to call the initProxy method, which also ends up binding the current instance VM to the _renderProxy property, with some error information added.

  6. Bind the _self attribute to the current instance VM, again the value of the current instance itself.

  7. Call some initialization methods and start some hook methods as follows:

    • initLifecycle(vm)

      Mount attributes for the current instance: $parent, $root, $chilren, $refs

      Mount private properties for the current instance: vm.\_watcher, vm.\_inactive, VM.\ _directInactive, VM.\ _isMounted, VM.\ _isDestroyed, vm._isbeingDestroyed

    • initEvents(vm)

      Mount private attributes for the current instance: _events, _hasHookEvent

    • initRender(vm)

      Mount attributes for instance: $vnode, $slots, $scopedSlots, $attrs, $Listeners

      Mount method for instance: $createElement

    • callHook(vm, ‘beforeCreate’)

      Triggers the execution of the beforeCreate hook function

    • initInjections(vm)

      Resolve the address Inject option

    • initProvide(vm)

      Parse the provide option

    • callHook(vm, ‘create’)

      Triggers the execution of the CREATE hook function

  8. Finally, call the $mount method on the instance and pass in the EL attribute.

MergeOptions method

The _init method does what mergeOptions does in step 4:

From the code above, we see thatmergeOptionsThe method receives three parameters, which are:

  • resolveConstructorOptionsMethod return value
  • optionsoptions
  • And the current instancevm

Options and vm we already very familiar with, is the incoming options, as well as the current instance objects, we first look at resolveConstructorOptions method, this method is defined under the current file, the code is as follows:

This method takes the constructor of the current instance, first saves the options on the constructor to the options variable, and then checks whether the constructor has anysuperProperty, if present, indicating that the constructor is created byVue.extendCreate the subclass constructor, where wenew VueThe Vue constructor is used, so you don’t go into the logical branch, which is left to exploreVue.extendStudy it carefully.resolveConstructorOptionsThe options method returns the options object directlyresolveConstructorOptionsThe method is to get the options above the constructor.

After understanding the resolveConstructorOptions method, mergeOptions method transfer at this time is clear, respectively is:

  • Option on constructor (argument 1)
  • Options passed in when instantiating (argument 2)
  • The current instance itselfvm(Parameter 3)

Let’s take a look at what mergeOptions does when it receives these three parameters:

  1. First, the second parameter passed in the development environment, that is, the parameter passed in the instantiation, is checked for the Components option. Verify that the component names in the Components option conform to the specification.

  2. Determines if the second argument passed in is a function, and if it is a function gets the option above the function. In our flow this parameter is an option object, not a function.

  3. Normalize the props property in parameter two.

  4. Standardize the Inject attribute in parameter 2.

  5. Standardize the directives attribute in parameter 2.

  6. The extends and mixins properties in parameter 2 are combined separately, and it is important to note that both properties are processed only if the second parameter does not contain the _base property. The _base attribute is an attribute that is bound to the Vue constructor during the loading phase of the Vue. If the _base option is included in the second parameter, the second parameter is a merged object that has been processed by the mergeOptions method. The extends and mixins are no longer processed for merged objects.

    The processing of these two properties is also easy to understand, which is to recursively call mergeOptions to mergeOptions. The details will be discussed when we explore these two properties.

  7. Create a new Options object and start merging parameter 1 object and parameter 2 object. The merge result is stored in the Options object. During the merge process, the mergeField method is called to obtain the merge strategy method.

  8. Finally, return the Options object.

The mergeOptions method is called to merge the parameters passed in to the Vue constructor and bind the merged result to the $options property of the current instance VM.

This is the end of the _init method. Of course, it only introduces the general flow of _init method. There are a lot of details that are not discussed in detail, because this article is mainly from the mainline perspective to understand the implementation process of new Vue. As for the details of the method implementation will be put into the corresponding API exploration in depth, interested people can also explore these details, then enter the $mount stage.

$mount method

At the end of the _init phase, the $mount method is called and the EL attribute is passed in, so let’s see what $mount does.

$mount method

During the loading of Vue in the previous article, we learned that the $mount method has two definitions, located in:

  • src/platforms/web/runtime/index.jsWhere the definition is public$mountmethods
  • src/platforms/web/entry-runtime-with-compiler.jsIn the

Why are there two definitions? In SRC/platforms/web/entry – the runtime – with – compiler. Js defined $before mount, will first define the public $mount method saved to mount attributes, and then covered to rewrite $mount method, The overridden $mount method is called at the end of the _init phase, and the public $mount method cached in the mount is called at the end of the overridden $mount, Can be roughly understand first call SRC/platforms/web/entry – the runtime – with – the compiler. In js $mount method for processing, Handle the call later SRC/platForms/web/runtime/index, js $mount method in the way of preparing for the final data mount.

Let’s first take a look at what the SRC /platforms/web/ entry-Runtime-with-compiler.js method does.

src/platforms/web/entry-runtime-with-compiler.jsThe $mount method in

$mount () {$mount () {$mount () {$mount () {$mount () {$mount () {$mount () {$mount () {$mount () {$mount ();

  • Query method is to convert the selector specified by EL into the corresponding DOM object. After obtaining the DOM object, make a step judgment. If the DOM object is a body tag or HTML tag, it will report a warning in the development environment. Vue does not allow el to specify a body tag or an HTML tag.

  • Next, save the $options option for the current instance in options, followed by a series of logical judgments, starting with the render method in Options:

    • If it doesn’t existrenderMethods: The process is as follows:

    After the above process processing will be obtainedtemplate, and then through the callcompileToFunctionsMethod and pass in the one obtained abovetemplateMethod, and finally getrenderMethods andstaticRenderFnsMethod and bind the two methods to the current instance. The last callmountMethods.

    The implementation of the compileToFunctions method will not matter, just know that the method is used to generate the Render method.

As you can see from the above, the purpose of $mount is to generate the render method, of course, if there was a render method in the first place (user-written render method), it would just skip this processing and go to the public $mount. Note: All Vue components require the Render method for rendering.

Let’s look at what the public $mount does.

src/platforms/web/runtime/index.jsThe $mount method in

The $mount method does the same for the el as before, and then calls the mountComponent method. The first parameter is the current instance object, the second parameter is the processed EL, and the third parameter is related to server rendering. Take a look at the mountComponent method.

MountComponent method

The definition of the method in the SRC/core/instance/lifecycle. Js, the contents of this method is as follows:

  1. The firstelBound to the current instance$elProperty, and then to the current instance$optionsDoes not exist in the optionsrenderThe case of the method is handled as follows.
  2. callbeforeMountDeclare periodic hook functions
  3. Define a variableupdateComponentAnd assign an arrow function whose content is the one calling the current instance_renderMethods.
  4. Instantiate the Watcher class and setupdateComponentAnd some other arguments.
  5. Do the mount state switch, andmountedCall to the lifecycle hook function
  6. Finally, the current instance is returnedvm

That’s basically what the mountComponent method does. Take a look at steps 3 and 4. The arrow function defined in step 3 is the method that triggers the page mount. The answer can be found by exploring step 4, which is triggered by instantiating Watcher, and how step 4 instantiates the Watcher class.

Instantiate the Watcher

Watcher classes defined in SRC/core/observer/Watcher. Js file.

After finding the definition of Watcher, I read through the comments that Watcher’s function is to monitor parsed expressions, collect dependencies, and then trigger callbacks when the expression changes. It’s kind of like an observer model. The new Watcher is instantiated in several places, and the specific implementation logic of Watcher is not focused on.

Go back to the source Watcher, the first initialized to examples of some of the properties, including the getter properties are stored is mount method, then at the end of the constructor calls the get () instance methods, see the get () the definition of instance method, found on mount method calls on its definition.

Here we know the trigger time of the mount method. When the mount method is triggered, the process of mounting begins.

conclusion

All init does is merge the options passed in at Vue instantiation with the options bound to the Vue constructor, and then mount some properties to the current instance.

The $mount method prepares the page for mounting, generates the render function, and finally executes the mount method.

That’s it for this article, and the rest will be covered in The Process of New Vue (Part 2).