Cet article présente principalement l'exemple de code source d'analyse du composant angulaire. Maintenant, je le partage avec vous et le donne comme référence.
Composant Web
Avant d'introduire le composant angulaire, comprenons brièvement les composants Web du W3C
Définition
Le W3C propose le standard de Web Component afin d'unifier la méthode standard de composantisation.
Chaque composant contient son propre code html, css et js.
Le standard des composants Web comprend les quatre concepts importants suivants :
1.Éléments personnalisés (balises personnalisées) : vous pouvez créer des balises et des éléments HTML personnalisés
2.Modèles HTML (modèles HTML) : utilisez < ;template> ; ; balise pour prédéfinir du contenu, mais il ne le charge pas dans la page, mais utilise du code JS pour l'initialiser
3 Shadow DOM (DOM virtuel) : vous pouvez créer un sous-arbre DOM complètement indépendant des autres éléments ; ;
4.Importations HTML : Une méthode d'introduction d'autres documents HTML dans des documents HTML, .
En résumé, la possibilité de créer des balises personnalisées pour introduire des composants est la base de la composantisation frontale. Les références aux fichiers HTML et aux modèles HTML sur la page sont utilisées pour prendre en charge l'écriture de vues de composants et la gestion des ressources des composants. Shadow DOM Il s'agit d'isoler les conflits et les impacts du code entre les composants.
Exemple
Définir hello-component
<template id="hello-template"> <style> h1 { color: red; } </style> <h1>Hello Web Component!</h1> </template> <script> // 指向导入文档,即本例的index.html var indexDoc = document; // 指向被导入文档,即当前文档hello.html var helloDoc = (indexDoc._currentScript || indexDoc.currentScript).ownerDocument; // 获得上面的模板 var tmpl = helloDoc.querySelector('#hello-template'); // 创建一个新元素的原型,继承自HTMLElement var HelloProto = Object.create(HTMLElement.prototype); // 设置 Shadow DOM 并将模板的内容克隆进去 HelloProto.createdCallback = function() { var root = this.createShadowRoot(); root.appendChild(indexDoc.importNode(tmpl.content, true)); }; // 注册新元素 var hello = indexDoc.registerElement('hello-component', { prototype: HelloProto }); </script>
Utiliser 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="赖祥燃, laixiangran@163.com, http://www.laixiangran.cn"/> <title>Web Component</title> <!--导入自定义组件--> <link rel="import" href="hello.html" rel="external nofollow" > </head> <body> <!--自定义标签--> <hello-component></hello-component> </body> </html>
Comme vous pouvez le voir dans le code ci-dessus, hello.html est un composant défini par le standard (nommé hello-component), et ce composant a son propre structure, style et logique, puis introduisez le fichier de composant dans index.html pour l'utiliser comme une balise normale.
Composant angulaire
Le composant angulaire est un type de directive et peut être compris comme une directive avec un modèle. Les deux autres types sont les directives d'attribut et les directives structurelles.
Composition de base
@Component({ selector: 'demo-component', template: 'Demo Component' }) export class DemoComponent {}
Décorateur de composants : chaque classe de composants doit utiliser @component Décoration est requis pour devenir un composant angulaire.
Métadonnées des composants : Métadonnées des composants : sélecteur, modèle, etc. Ce qui suit se concentrera sur la signification de chaque métadonnée.
Classe de composant : le composant est en fait une classe ordinaire, et la logique du composant est définie et implémentée dans la classe de composant.
Modèle de composant : Chaque composant est associé à un modèle, qui sera finalement rendu sur la page. L'élément DOM de la page est l'élément hôte de cette instance de composant.
Métadonnées des composants
Propriétés des métadonnées personnelles
名称 | 类型 | 作用 |
---|---|---|
animations | AnimationEntryMetadata[] | 设置组件的动画 |
changeDetection | ChangeDetectionStrategy | 设置组件的变化监测策略 |
encapsulation | ViewEncapsulation | 设置组件的视图包装选项 |
entryComponents | any[] | 设置将被动态插入到该组件视图中的组件列表 |
interpolation | [string, string] | 自定义组件的插值标记,默认是双大括号 |
moduleId | string | 设置该组件在 ES/CommonJS 规范下的模块id,它被用于解析模板样式的相对路径 |
styleUrls | string[] | 设置组件引用的外部样式文件 |
styles | string[] | 设置组件使用的内联样式 |
template | string | 设置组件的内联模板 |
templateUrl | string | 设置组件模板所在路径 |
viewProviders | Provider[] | 设置组件及其所有子组件(不含ContentChildren)可用的服务 |
Héritées du noyau/de la directive
名称 | 类型 | 作用 |
---|---|---|
exportAs | string | 设置组件实例在模板中的别名,使得可以在模板中调用 |
host | {[key: string]: string} | 设置组件的事件、动作和属性等 |
inputs | string[] | 设置组件的输入属性 |
outputs | string[] | 设置组件的输出属性 |
providers | Provider[] | 设置组件及其所有子组件(含ContentChildren)可用的服务(依赖注入) |
queries | {[key: string]: any} | 设置需要被注入到组件的查询 |
selector | string | 设置用于在模板中识别该组件的css选择器(组件的自定义标签) |
几种元数据详解
以下几种元数据的等价写法会比元数据设置更简洁易懂,所以一般推荐的是等价写法。
inputs
@Component({ selector: 'demo-component', inputs: ['param'] }) export class DemoComponent { param: any; }
等价于:
@Component({ selector: 'demo-component' }) export class DemoComponent { @Input() param: any; }
outputs
@Component({ selector: 'demo-component', outputs: ['ready'] }) export class DemoComponent { ready = new eventEmitter<false>(); }
等价于:
@Component({ selector: 'demo-component' }) export class DemoComponent { @Output() ready = new eventEmitter<false>(); }
host
@Component({ selector: 'demo-component', host: { '(click)': 'onClick($event.target)', // 事件 'role': 'nav', // 属性 '[class.pressed]': 'isPressed', // 类 } }) export class DemoComponent { isPressed: boolean = true; onClick(elem: HTMLElement) { console.log(elem); } }
等价于:
@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); } }
queries - 视图查询
@Component({ selector: 'demo-component', template: ` <input #theInput type='text' /> <p>Demo Component</p> `, queries: { theInput: new ViewChild('theInput') } }) export class DemoComponent { theInput: ElementRef; }
等价于:
@Component({ selector: 'demo-component', template: ` <input #theInput type='text' /> <p>Demo Component</p> ` }) export class DemoComponent { @ViewChild('theInput') theInput: ElementRef; }
queries - 内容查询
<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>; }
等价于:
@Component({ selector: 'my-list', template: ` <ul> <ng-content></ng-content> </ul> ` }) export class MyListComponent { @ContentChild(ListItem) items: QueryList<ListItem>; }
styleUrls、styles
styleUrls和styles允许同时指定。
优先级:模板内联样式 > styleUrls > styles。
建议:使用styleUrls引用外部样式表文件,这样代码结构相比styles更清晰、更易于管理。同理,模板推荐使用templateUrl引用模板文件。
changeDetection
ChangeDetectionStrategy.Default:组件的每次变化监测都会检查其内部的所有数据(引用对象也会深度遍历),以此得到前后的数据变化。
ChangeDetectionStrategy.OnPush:组件的变化监测只检查输入属性(即@Input修饰的变量)的值是否发生变化,当这个值为引用类型(Object,Array等)时,则只对比该值的引用。
显然,OnPush策略相比Default降低了变化监测的复杂度,很好地提升了变化监测的性能。如果组件的更新只依赖输入属性的值,那么在该组件上使用OnPush策略是一个很好的选择。
encapsulation
ViewEncapsulation.None:无 Shadow DOM,并且也无样式包装。
ViewEncapsulation.Emulated:无 Shadow DOM,但是通过Angular提供的样式包装机制来模拟组件的独立性,使得组件的样式不受外部影响,这是Angular的默认设置。
ViewEncapsulation.Native:使用原生的 Shadow DOM 特性。
生命周期
当Angular使用构造函数新建组件后,就会按下面的顺序在特定时刻调用这些生命周期钩子方法:
生命周期钩子 | 调用时机 |
---|---|
ngOnChanges | 在ngOnInit之前调用,或者当组件输入数据(通过@Input装饰器显式指定的那些变量)变化时调用。 |
ngOnInit | 第一次ngOnChanges之后调用。建议此时获取数据,不要在构造函数中获取。 |
ngDoCheck | 每次变化监测发生时被调用。 |
ngAfterContentInit | 使用 |
ngAfterContentChecked | ngAfterContentInit后被调用,或者每次变化监测发生时被调用(只适用组件)。 |
ngAfterViewInit | 创建了组件的视图及其子视图之后被调用(只适用组件)。 |
ngAfterViewChecked | ngAfterViewInit,或者每次子组件变化监测时被调用(只适用组件)。 |
ngOnDestroy | 销毁指令/组件之前触发。此时应将不会被垃圾回收器自动回收的资源(比如已订阅的观察者事件、绑定过的DOM事件、通过setTimeout或setInterval设置过的计时器等等)手动销毁掉。 |
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!