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:
-
: Create components by extending Vue instance
-
: 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 constructor
function 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,components
Property, 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 parsescomponents
Attributes, 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 < l; i++) { var key = ids[i]; if ((key) || (key)) { 'development' !== 'production' && warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + key); continue; } // record a all lowercase <-> 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.