SoFunction
Updated on 2025-04-04

How to implement source code analysis of components in Vue

The official website has two categories of component inheritance, global components and local components. Either way, the most important thing is to create components and then register components according to the scenario.

One thing to remember is that "components are actually extended Vue instances"!

1. Global Components

// Method 1var MyComponent = ({
  name: 'my-component',
  template: '<div>A custom component!</div>'
});
('my-component', MyComponent);

// Method 2('my-component', {
  name: 'my-component',
  template: '<div>A custom component!</div>'
});

//Use components<div >
  <my-component></my-component>
</div>

There are two static methods involved:

  1. : Create components by extending Vue instance
  2. : Register components

Let's take a look firstSource code, please refer to Chinese comments for explanation:

 = function (extendOptions) {
 extendOptions = extendOptions || {};
 var Super = this;
 var isFirstExtend =  === 0;
 if (isFirstExtend && extendOptions._Ctor) {
  return extendOptions._Ctor;
 }
 var name =  || ;
 // If there is a name attribute, that is, the component name, check whether the name spelling is legal. if ('development' !== 'production') {
  if (!/^[a-zA-Z][\w-]*$/.test(name)) {
   warn('Invalid component name: "' + name + '". Component names ' + 'can only contain alphanumeric characaters and the hyphen.');
   name = null;
  }
 }
 // Create a VueComponent constructor with the function name 'VueComponent' or name var Sub = createClass(name || 'VueComponent');
 // Constructor prototype inheritance  = ();
  = Sub;
  = cid++;
 // Merge and extendOptions as static properties options for the new constructor  = mergeOptions(, extendOptions);
 //The static property of 'super' points to the Vue function Sub['super'] = Super;
 // start---------------------------------------------------------------------------------------------------------------------------- // allow further extension
  = ;
 // create asset registers, so extended classes
 // can have their private assets too.
 config._assetTypes.forEach(function (type) {
  Sub[type] = Super[type];
 });
 // end---------------------------------------------------------------------------------------------------------------------------- // enable recursive self-lookup
 if (name) {
  [name] = Sub;
 }
 // cache constructor: cache the constructor if (isFirstExtend) {
  extendOptions._Ctor = Sub;
 }
 return Sub;
};

You can see,The key point is to create a constructorfunction VueComponent(options) { this._init(options) },The properties and methods on the Vue prototype are inherited through the prototype chain, and then the static function of Vue is assigned to the constructor.

Take a look againSource code, please refer to Chinese comments for explanation:

// _assetTypes: ['component', 'directive', 'elementDirective', 'filter', 'transition', 'partial']
config._assetTypes.forEach(function (type) {
 // Static method Vue[type] = function (id, definition) {
  if (!definition) {
   return [type + 's'][id];
  } else {
   /* istanbul ignore if */
   if ('development' !== 'production') {
    if (type === 'component' && ((id) || (id))) {
     warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + id);
    }
   }
   // If the second parameter is a simple object, you need to create a component constructor   if (type === 'component' && isPlainObject(definition)) {
    if (!) {
      = id;
    }
    definition = (definition);
   }
   // Add component functions to Vue static properties, that is, globally inject the component   [type + 's'][id] = definition;
   return definition;
  }
 };
});

methodThe key point is to inject component functions into Vue static properties, so that the corresponding constructor can be found based on the component name, thereby creating component instances.

2. Local components

var MyComponent = ({
  template: '<div>A custom component!</div>'
});

new Vue({
  el: '#example',
  components: {
    'my-component': MyComponent,
    'other-component': {
      template: '<div>A custom component!</div>'
    }
  }
});

The feature of registering local components is that when creating Vue instances,componentsProperty, this property is a simple object, the key value is the component name, the value can be a specific component function, or the options object that must be created for the component.

Let's see how Vue parsescomponentsAttributes, explanation reference Chinese comments:

._init = function (options) {
  options = options || {};
  ....
  // merge options.
  options = this.$options = mergeOptions(, options, this);
  ...
};

function mergeOptions(parent, child, vm) {
  //Resolve components attribute  guardComponents(child);
  guardProps(child);
  ...
}

function guardComponents(options) {
  if () {
    // Convert object to array    var components =  = guardArrayAssets();
    //ids array contains component name    var ids = (components);
    var def;
    if ('development' !== 'production') {
      var map = options._componentNameMap = {};
    }
    // Iterate over component array    for (var i = 0, l = ; i &lt; l; i++) {
      var key = ids[i];
      if ((key) || (key)) {
        'development' !== 'production' &amp;&amp; warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + key);
        continue;
      }
      // record a all lowercase &lt;-&gt; kebab-case mapping for
      // possible custom element case error warning
      if ('development' !== 'production') {
        map[(/-/g, '').toLowerCase()] = hyphenate(key);
      }
      def = components[key];
      // If the component definition is a simple object-object literal, then you need to create a component function based on the object      if (isPlainObject(def)) {
        components[key] = (def);
      }
    }
  }
}

During the process of creating a Vue instance, after the guardComponents() function is processed, it can be ensured that the components attributes in the Vue instance are all from{Component name:Component function}Constructed, in this way, in subsequent use, you can directly use the component building function inside the instance to create component instances.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.