Web Component
Before introducing Angular Components, let’s take a quick look at W3C Web Components
define
- W3C proposed a standard for Web Component to unify the componentization standard approach.
- Each component contains its own HTML, CSS, and JS code.
- The Web Component standard includes four important concepts:
- Custom Elements: You can create Custom HTML tags and Elements;
- HTML Templates: Use
<template>
The tag pre-defines something, but instead of loading it into the page, it initializes it with JS code. - Shadow DOM (virtual DOM) : You can create DOM subtrees that are completely independent of other elements.
- HTML Imports: A method of introducing other HTML documents into an HTML document,
<link rel="import" href="example.html" />
.
In a word, the ability to create custom tags to introduce components is the basis for componentization of the front end, reference HTML files and HTML templates in the page is used to support writing component views and component resource management, and Shadow DOM is used to isolate conflicts and impacts of code between components.
The sample
Define the hello – component
<template id="hello-template">
<style>
h1 {
color: red;
}
</style>
<h1>Hello Web Component!</h1>
</template>
<script>
// Points to the imported document, in this case index.html
var indexDoc = document;
// Points to the imported document, the current document hello.html
var helloDoc = (indexDoc._currentScript || indexDoc.currentScript).ownerDocument;
// Get the template above
var tmpl = helloDoc.querySelector('#hello-template');
// Create a new element prototype that inherits from HTMLElement
var HelloProto = Object.create(HTMLElement.prototype);
// Set Shadow DOM and clone the template into it
HelloProto.createdCallback = function() {
var root = this.createShadowRoot();
root.appendChild(indexDoc.importNode(tmpl.content, true));
};
// Register a new element
var hello = indexDoc.registerElement('hello-component', {
prototype: HelloProto
});
</script>
Copy the code
Use the hello – component
<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 Xiang combustion, [email protected], http://www.laixiangran.cn"/>
<title>Web Component</title>
<! Import custom components -->
<link rel="import" href="hello.html">
</head>
<body>
<! -- Custom tags -->
<hello-component></hello-component>
</body>
</html>
Copy the code
As you can see from the above code, hello.html is a standard defined component (named Hello-component) that has its own structure, style, and logic. You can then import the component file into index.html and use it as a normal tag.
Angular Component
Angular Component is a type of directive that can be understood as having a template. The other two are attribute and structural directives.
The basic composition of
@Component({
selector: 'demo-component',
template: 'Demo Component'
})
export class DemoComponent {}
Copy the code
- Component decorator: must be used by each component class
@component
Decorates to become an Angular component. - Component metadata:
selector
,template
The following sections will focus on the meaning of each metadata. - Component classes: A component is actually a normal class in which the logic of the component is defined and implemented.
- Component templates: Each component is associated with a template that will eventually be rendered to the page, this one on the page
DOM
The element is the host element for this component instance.
Component metadata
Own metadata attributes
The name of the | type | role |
---|---|---|
animations | AnimationEntryMetadata[] |
Sets the animation of the component |
changeDetection | ChangeDetectionStrategy |
Sets the change monitoring policy for the component |
encapsulation | ViewEncapsulation |
Sets the view wrapping options for the component |
entryComponents | any[] |
The Settings will be dynamically inserted into the list of components in the component view |
interpolation | [string, string] |
Interpolation tag for a custom component. Default is double curly braces{{}} |
moduleId | string |
Sets the module ID of this component under the ES/CommonJS specification, which is used to resolve the relative path to the template style |
styleUrls | string[] |
Sets the external style file referenced by the component |
styles | string[] |
Sets the inline style used by the component |
template | string |
Sets the inline template for the component |
templateUrl | string |
Set the path where the component template resides |
viewProviders | Provider[] |
Sets the services available to the component and all its children (excluding ContentChildren) |
From the core/Directive to inherit
The name of the | type | role |
---|---|---|
exportAs | string |
Aliases the component instance in the template so that it can be invoked in the template |
host | {[key: string]: string} |
Sets the component’s events, actions, properties, and so on |
inputs | string[] |
Sets the input properties of the component |
outputs | string[] |
Sets the output properties of the component |
providers | Provider[] |
Sets the services (dependency injection) available to the component and all its children, including ContentChildren |
queries | {[key: string]: any} |
Sets the query that needs to be injected into the component |
selector | string |
Set the CSS selector used to identify the component in the template (the component’s custom tag) |
Several metadata details
The equivalent syntax of the following metadata is more concise than metadata Settings. Therefore, the equivalent syntax is recommended.
inputs
@Component({
selector: 'demo-component',
inputs: ['param']})export class DemoComponent {
param: any;
}
Copy the code
Is equivalent to:
@Component({
selector: 'demo-component'
})
export class DemoComponent {
@Input() param: any;
}
Copy the code
outputs
@Component({
selector: 'demo-component',
outputs: ['ready']})export class DemoComponent {
ready = new eventEmitter<false> (); }Copy the code
Is equivalent to:
@Component({
selector: 'demo-component'
})
export class DemoComponent {
@Output() ready = new eventEmitter<false> (); }Copy the code
host
@Component({
selector: 'demo-component',
host: {
'(click)': 'onClick($event.target)'./ / event
'role': 'nav'./ / property
'[class.pressed]': 'isPressed'./ / class}})export class DemoComponent {
isPressed: boolean = true;
onClick(elem: HTMLElement) {
console.log(elem); }}Copy the code
Is equivalent to:
@Component({
selector: 'demo-component'
})
export class DemoComponent {
@HostBinding('attr.role') role = 'nav';
@HostBinding('class.pressed') isPressed: boolean = true;
@HostListener('click'['$event.target'])
onClick(elem: HTMLElement) {
console.log(elem); }}Copy the code
Queries – View queries
@Component({
selector: 'demo-component',
template: `
Demo Component
`,
queries: {
theInput: new ViewChild('theInput')}})export class DemoComponent {
theInput: ElementRef;
}
Copy the code
Is equivalent to:
@Component({
selector: 'demo-component',
template: `
Demo Component
`
})
export class DemoComponent {
@ViewChild('theInput') theInput: ElementRef;
}
Copy the code
Queries – Content query
<my-list>
<li *ngFor="let item of items;">{{item}}</li>
</my-list>
Copy the code
@Directive({
selector: 'li'
})
export class ListItem {}
Copy the code
@Component({
selector: 'my-list',
template: `
`,
queries: {
items: new ContentChild(ListItem)
}
})
export class MyListComponent {
items: QueryList<ListItem>;
}
Copy the code
Is equivalent to:
@Component({
selector: 'my-list',
template: `
`
})
export class MyListComponent {
@ContentChild(ListItem) items: QueryList<ListItem>;
}
Copy the code
StyleUrls, styles,
-
StyleUrls and styles can be specified at the same time.
-
Priority: template inline Style > styleUrls > styles.
-
Tip: 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 that you use templateUrl to reference the template file.
changeDetection
-
ChangeDetectionStrategy. Default: of every change monitoring components will check all of its internal data (reference object may also depth traversal), in order to get data before and after the change.
-
ChangeDetectionStrategy. OnPush: component change monitoring only check Input attribute (i.e., @ the variables of Input modification) whether the value of the change, when the value of a reference type (Object, Array, etc.), then only the value of reference.
-
Obviously, compared with Default, OnPush reduces the complexity of change monitoring and improves the performance of change monitoring. Using an OnPush strategy on a component is a good choice if the component’s updates depend only on the values of the input properties.
encapsulation
-
ViewEncapsulation.None: No Shadow DOM, and no style wrapping.
-
ViewEncapsulation. Emulated: no Shadow DOM, but by presents to provide style packaging mechanism to simulate the independence of the components, makes the style of the component is not affected by the external, this is the default setting of presents.
-
ViewEncapsulation.Native: Uses the Native Shadow DOM feature.
The life cycle
When Angular creates a component using a constructor, it calls the lifecycle hook methods at specific times in the following order:
Lifecycle hook | Call time |
---|---|
ngOnChanges | Called before ngOnInit, or when the component enters data (through@Input Called when those variables explicitly specified by the decorator change. |
ngOnInit | Called after the first ngOnChanges.It is recommended to get the data at this point, not in the constructor. |
ngDoCheck | Called each time change monitoring occurs. |
ngAfterContentInit | Called after embedding external content into the component view, called after the first ngDoCheck and executed only once (for components only). |
ngAfterContentChecked | Called after ngAfterContentInit, or every time change monitoring occurs (component only). |
ngAfterViewInit | Called after the component’s view and its child views are created (component only). |
ngAfterViewChecked | NgAfterViewInit, or called every time a child component changes are monitored (component only). |
ngOnDestroy | Fired before destroying instructions/components. Resources that are not automatically collected by the garbage collector (Such as subscribed observer events, bound DOM events, timers set with setTimeout or setInterval, and so on) Manually destroy it. |
Please indicate the source of reprint, thank you!