SoFunction
Updated on 2025-04-04

Description of the difference between vue $mount and el

There is no difference in the use effect between the two, both to mount the instantiated vue into the specified dom element.

If el is specified when instantiating vue, the vue will be rendered in the dom corresponding to this el. Otherwise, if el is not specified, the vue instance will be in a "unmounted" state, and the mount can be manually performed through $mount.

Note: If $mount does not provide parameters, the template will be rendered as an element outside the document, and you must insert it into the document using the native DOM API.

For example:

var MyComponent = ({
 template: '<div>Hello!</div>'
})

// Create and mount to #app (replaces #app)new MyComponent().$mount('#app')
// Same as abovenew MyComponent({ el: '#app' })

// Or, render outside the document and then mountvar component = new MyComponent().$mount()
('app').appendChild(component.$el)

Supplementary knowledge:Implementation of Vue instance mount method ($mount)

The two life cycle hooks beforeCreate and created have been called back in Vue's _init method, and the instance is mounted after that.

  if (vm.$) { // Mount instance   vm.$mount(vm.$);
  }

In the mount function, beforeMount and mounted callbacks will be made.

There are differences in the implementation of the $mount function under different platforms. Consider the runtime-with-compiler version of the web platform. The definition of the web platform is as follows (src/platforms/web/runtime/)

import { mountComponent } from 'core/instance/lifecycle';

.$mount = function(
 el?: string | Element,
 hydrating?: boolean
): Component {
 el = el && inBrowser ? query(el) : undefined;
 
 return mountComponent(this, el, hydrating);
};

Among the parameters of the $mount function, the first one is the el of our attribute and the second one is related to server rendering. It is used in the patch function and can be ignored here.

However, when calling this $mount function, the first thing you call is the $mount function under different versions, and then the $mount function of the corresponding platform is called in the function. As shown in the runtime-with-compiler version, the $mount function is as follows (src/platforms/web/)

import Vue from './runtime/index';
const mount = .$mount; // Cache $mount method above.$mount = function(
 el?: string | Element,
 hydrating?: boolean
): Component {
 el = el && query(el);

 // Cannot be mounted on body and html if (el ===  || el === ) {   
  return this;
 }

 const options = this.$options;

 if (!) { // If there is no render function  // ... Add render function to options   const { render, staticRenderFns } = compileToFunctions(template, {
    outputSourceRange : .NODE_ENV !== 'production',
    shouldDecodeNewlines,
    shouldDecodeNewlinesForHref,
    delimiters    : ,
    comments     : ,
   }, this);

    = render;
    = staticRenderFns;
  // ...
 }
 
 return (this, el, hydrating);
};

It can be seen that this function mainly does three things

1. Since the mounted object will be replaced after mount, it cannot be mounted on body and html.

2. If the current Vue instance does not have a render() function (write template, etc.), add the render function to options through compilation and other means.

3. Call the $mount method we cache first at the beginning of the code. This method is the method under the web platform.

The $mount method under the web platform mainly calls the mountComponent() method. Next, our core is this method

In the 'core/instance/ file, we found the definition of this method, deleted some non-key code and as follows

export function mountComponent(
 vm: Component,
 el: ?Element,
 hydrating?: boolean
): Component {
 vm.$el = el;
 if (!vm.$) { 
  // Not the point, this is mainly used to make some error prompts without render function }
 callHook(vm, 'beforeMount'); // Callback beforeMount, start preparing to mount the instance
 // Declare the function to update the component (the performance configuration in the source code is not the focus, so it is omitted) const updateComponent = updateComponent = () => {
   vm._update(vm._render(), hydrating);
 };

 // new one Watcher [isRenderWatcher] new Watcher(vm, updateComponent, noop, {
  before() {
   if (vm._isMounted && !vm._isDestroyed) {
    callHook(vm, 'beforeUpdate');
   }
  },
 }, true /* isRenderWatcher */);
 hydrating = false;

 // The mounted callback for the root instance of Vue is executed here if (vm.$vnode == null) {
  vm._isMounted = true;
  callHook(vm, 'mounted');
 }
 
 return vm;
}

The above code mainly does the following three things

1. Callback beforeMount

2. Generate updateComponent method, which renders vnode into a real DOM

3. New a Watcher and call the updateComponent method in the Watcher

4. Callback mounted

For the updateComponent method, it mainly calls _update() to render vnode as the real DOM displayed on the browser.

We consider the following two issues

1. How to call the updateComponent method in Watcher

The constructor of the Watcher function accepts the following parameters

constructor(
  vm: Component,
  expOrFn: string | Function,
  cb: Function,
  options?: ?Object,
  isRenderWatcher?: boolean
 )

In the above code, the updateComponent() method is passed as the second parameter, that is, the expOrFn in the constructor

You will see it when you look down

  if (typeof expOrFn === 'function') {
    = expOrFn;
  }

That is to say, the updateComponent() method is set to getter() method

See the end of the constructor

   = 
   ? undefined
   : ();

The value of the lazy attribute is set to false in front of it

= !!; // We do not have lazy attribute in options

This means that the end of the i constructor will call(), and in ()

  const vm = ;
  try {
   value = (vm, vm);
  }

We see that the getter() method is called, that is, the updateComponent() method is called.

2. Why is the $vnode of the root instance empty

In the initRender() function, there is the following code

const parentVnode = vm.$vnode = options._parentVnode;

That is to say, the current actual $vnode value is the vnode value of its parent node

The root instance has no parent node, so its $vnode value is empty, so it will be executed

 if (vm.$vnode == null) {
  vm._isMounted = true;
  callHook(vm, 'mounted');
 }

So where is the mounted callback of the child node executed?

There is the following code in the path()(core/vdom/) function

 function invokeInsertHook(vnode, queue, initial) {
  if (isTrue(initial) && isDef()) {
    = queue;
  }
  else {
   for (let i = 0; i < ; ++i) {
    queue[i].(queue[i]); // here   }
  }
 }

When looping queue, the insert() method is called, which is VNodeHooks, which is declared in componentVNodeHooks(core/vdom/). The code is as follows

const componentVNodeHooks = {
 insert(vnode: MountedComponentVNode) {
  const { context, componentInstance } = vnode;

  if (!componentInstance._isMounted) {
   componentInstance._isMounted = true;
   callHook(componentInstance, 'mounted'); // here  }
  if () {
   if (context._isMounted) {
    queueActivatedComponent(componentInstance);
   }
   else {
    activateChildComponent(componentInstance, true /* direct */);
   }
  }
 },
}

Since the path() method is called in the _update() function, this will not be highlighted.

In the next section, we will talk about the implementation of render() and _update() methods.

The above explanation of the difference between vue $mount and el is all the content I share with you. I hope you can give you a reference and I hope you can support me more.