Web Component
Before introducing Angular Component, let's take a brief look at itW3C Web Components
definition
W3C proposes Web Component standards as a unified component standard.
Each component contains its own HTML, CSS, and JS code.
The Web Component standard includes the following four important concepts:
Elements: You can create custom HTML tags and elements;
Templates (HTML template): Use the <template> tag to predefined some content, but it is not loaded to the page, but uses JS code to initialize it;
DOM (virtual DOM): It is possible to create DOM subtrees that are completely independent of other elements;
Imports: A method to introduce other HTML documents into HTML documents, <link rel="import" href="" rel="external nofollow" />.
In summary, it is possible to create custom tags to introduce components to the basis of front-end componentization. References to HTML files and HTML templates on the page are used to support writing component views and component resource management, while Shadow DOM isolates the conflicts and impacts of code between components.
Example
Definition hello-component
<template > <style> h1 { color: red; } </style> <h1>Hello Web Component!</h1> </template> <script> // Point to the import document, that is, the var indexDoc = document; // Point to the imported document, that is, the current document var helloDoc = (indexDoc._currentScript || ).ownerDocument; // Get the template above var tmpl = ('#hello-template'); // Create a prototype of a new element, inherited from HTMLElement var HelloProto = (); // Set Shadow DOM and clone the contents of the template in = function() { var root = (); ((, true)); }; // Register new elements var hello = ('hello-component', { prototype: HelloProto }); </script>
Using hello-component
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-COMPATIBLE" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="author" content="Lai Xiangran, laixiangran@, "/> <title>Web Component</title> <!--Import custom components--> <link rel="import" href="" rel="external nofollow" > </head> <body> <!--Custom Tags--> <hello-component></hello-component> </body> </html>
From the above code, we can see that for a component defined by the standard (named hello-component), there is its own structure, style and logic in this component. Then, the component file is introduced in it, and it can be used like a normal label.
Angular Component
Angular Component is a type of directive, which can be understood as a directive with a template. The other two are attribute instructions and structure instructions.
Basic composition
@Component({ selector: 'demo-component', template: 'Demo Component' }) export class DemoComponent {}
- Component Decorator: Each component class must be decorated with @component to become an Angular component.
- Component metadata: Component metadata: selector, template, etc. The following will focus on explaining the meaning of each metadata.
- Component class: Components are actually also ordinary classes, and the logic of components is defined and implemented in component classes.
- Component template: Each component will be associated with a template, and this template will eventually be rendered on the page. The DOM element on the page is the host element of this component instance.
Component metadata
Its own metadata attributes
name | type | effect |
---|---|---|
animations | AnimationEntryMetadata[] | Set the component animation |
changeDetection | ChangeDetectionStrategy | Setting up component change monitoring strategies |
encapsulation | ViewEncapsulation | Set the view wrapper options for components |
entryComponents | any[] | Set the list of components that will be dynamically inserted into the component view |
interpolation | [string, string] | Interpolation marks for custom components, default to double braces |
moduleId | string | Sets the module id of this component under the ES/CommonJS specification, which is used to parse the relative path of the template style |
styleUrls | string[] | Set external style files referenced by components |
styles | string[] | Set the inline style used by the component |
template | string | Set up the component's inline template |
templateUrl | string | Set the path where the component template is located |
viewProviders | Provider[] | Set up the services available to the component and all its subcomponents (excluding ContentChildren) |
Inherited from core/Directive
name | type | effect |
---|---|---|
exportAs | string | Sets the alias of component instances in the template so that they can be called in the template |
host | {[key: string]: string} | Sets the events, actions, properties, etc. of the component |
inputs | string[] | Set the input properties of the component |
outputs | string[] | Set the output properties of the component |
providers | Provider[] | Sets the available services (dependency injection) for the component and all its subcomponents (including ContentChildren) |
queries | {[key: string]: any} | Set up queries that need to be injected into the component |
selector | string | Set the css selector (component's custom tag) to identify the component in the template |
Several metadata explanations
The following equivalent writing methods for metadata will be more concise and easy to understand than metadata settings, so the general recommendation is the equivalent writing method.
inputs
@Component({ selector: 'demo-component', inputs: ['param'] }) export class DemoComponent { param: any; }
Equivalent to:
@Component({ selector: 'demo-component' }) export class DemoComponent { @Input() param: any; }
outputs
@Component({ selector: 'demo-component', outputs: ['ready'] }) export class DemoComponent { ready = new eventEmitter<false>(); }
Equivalent to:
@Component({ selector: 'demo-component' }) export class DemoComponent { @Output() ready = new eventEmitter<false>(); }
host
@Component({ selector: 'demo-component', host: { '(click)': 'onClick($)', // event 'role': 'nav', // Attributes '[]': 'isPressed', // kind } }) export class DemoComponent { isPressed: boolean = true; onClick(elem: HTMLElement) { (elem); } }
Equivalent to:
@Component({ selector: 'demo-component' }) export class DemoComponent { @HostBinding('') role = 'nav'; @HostBinding('') isPressed: boolean = true; @HostListener('click', ['$']) onClick(elem: HTMLElement) { (elem); } }
queries - View Query
@Component({ selector: 'demo-component', template: ` <input #theInput type='text' /> <div>Demo Component</div> `, queries: { theInput: new ViewChild('theInput') } }) export class DemoComponent { theInput: ElementRef; }
Equivalent to:
@Component({ selector: 'demo-component', template: ` <input #theInput type='text' /> <div>Demo Component</div> ` }) export class DemoComponent { @ViewChild('theInput') theInput: ElementRef; }
queries - Content Query
<my-list> <li *ngFor="let item of items;">{{item}}</li> </my-list>
@Directive({ selector: 'li' }) export class ListItem {}
@Component({ selector: 'my-list', template: ` <ul> <ng-content></ng-content> </ul> `, queries: { items: new ContentChild(ListItem) } }) export class MyListComponent { items: QueryList<ListItem>; }
Equivalent to:
@Component({ selector: 'my-list', template: ` <ul> <ng-content></ng-content> </ul> ` }) export class MyListComponent { @ContentChild(ListItem) items: QueryList<ListItem>; }
styleUrls、styles
styleUrls and styles are allowed to be specified simultaneously.
Priority: Template inline styles > styleUrls > styles.
Recommendation: Use styleUrls to refer to external stylesheet files, so that the code structure is clearer and easier to manage than styles. Similarly, it is recommended to use templateUrl to reference template files.
changeDetection
: Each change monitoring of a component will check all data inside it (reference objects will also be traversed deeply) to obtain the previous and subsequent data changes.
: Component change monitoring only checks whether the value of the input attribute (i.e., the variable modified by @Input) has changed. When this value is a reference type (Object, Array, etc.), only the reference of the value is compared.
Obviously, the OnPush strategy reduces the complexity of change monitoring compared to Default, which greatly improves the performance of change monitoring. If the update of a component depends only on the value of the input attribute, then using the OnPush strategy on that component is a good choice.
encapsulation
: No Shadow DOM, and no style wrapping.
: No Shadow DOM, but the style wrapping mechanism provided by Angular simulates component independence, so that the style of component is not affected by external influences. This is the default setting of Angular.
: Use native Shadow DOM features.
life cycle
When Angular creates a new component using the constructor, these life cycle hook methods are called at a specific moment in the following order:
Life cycle hook | Call time |
---|---|
ngOnChanges | Called before ngOnInit, or when component input data (those variables explicitly specified via the @Input decorator) change. |
ngOnInit | Called after the first ngOnChanges. It is recommended to get the data at this time and do not get it in the constructor. |
ngDoCheck | Called every time the change monitoring occurs. |
ngAfterContentInit | use |
ngAfterContentChecked | ngAfterContentInit is called after, or is called every time the change monitoring occurs (components only). |
ngAfterViewInit | The view of the component and its subviews are called after creating (components only). |
ngAfterViewChecked | ngAfterViewInit, or is called every time the child component changes are monitored (components only). |
ngOnDestroy | Triggered before destroying the directive/component. At this time, resources that are not automatically recycled by the garbage collector (such as subscribed observer events, bound DOM events, timers set through setTimeout or setInterval, etc.) should be manually destroyed. |
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.