Dans le processus de développement de composants Angular, nous avons l'habitude d'écrire le style du composant dans le fichier CSS correspondant, mais nous n'avons jamais compris comment Angular réalise l'isolation de style. Par exemple, dans le composant A, nous écrivons. h1 { color: red, ce style ne prendra effet que dans le composant A et n'affectera pas les autres composants. Afin d'explorer le principe, cet article est créé. Le contenu suivant est basé sur Angular CLI version 10.1.1. h1 { color: red }
,这个样式只会在 A 组件中生效,而不会影响到其他的组件。为了探究原理,就有了这篇文章,以下内容基于 Angular CLI 10.1.1 版本创建。
首先用 Angular CLI 创建一个新的 Angular 项目,删除 app.component.html
中的所有内容,替换成如下内容:
<h1>App Component</h1> <button class="red-button">Button</button>
在 app.component.css
中添加如下内容:
.red-button { color: red; }
运行时有如下 html 代码:
<app-root _nghost-ydo-c11="" ng-version="10.1.1"> <h2 _ngcontent-ydo-c11="">App component</h2> <button _ngcontent-ydo-c11="" class="red-button">Button</button> </app-root>
可以看到在在 app-root
元素上有一个名为 _nghost-ydo-c11
的属性(property),app-root
里面的两个元素都有一个名为 _ngcontent-ydo-c11
的属性。【相关教程推荐:《angular教程》】
那么这些属性是用来做什么的呢?
为了更好的理解,我们先创建一个独立的组件,新建文件 blue-button.component.ts
,内容如下:
import { Component } from '@angular/core'; @Component({ selector: 'app-blue-button', template: ` <h2>Blue button component</h2> <button class="blue-button">Button</button> `, styles: [` .blue-button { background: blue; } `] }) export class BlueButtonComponent {}
放到 app.component.html
中运行后,会看到如下 html 代码:
可以看到 app-blue-button
中也有一个以 _nghost-xxx
开头的属性,还有一个和 app-root
中其他元素相同的属性。而在组件里面的两个元素都有名为 _ngcontent-yke-c11
的属性。
由于每次运行,Angular 生成的属性字符串都是随机的,所以后面的代码如果出现了类似的属性都是按照这个截图对应的。
通过观察我们可以总结出:
_nghost_xxx
_ngcontent_xxx
那么这些属性是怎样用于样式隔离的呢?
这些属性可以和 CSS 结合起来,比如当我们查看例子中蓝色按钮的样式时,会看到这样的 css:
.blue-button[_ngcontent-yke-c11] { background: blue; }
可以看出,Angular 通过这种方式使 blue-button
类只能应用于有这个属性的元素上,而不会影响到其他组件中的元素。
知道了 Angular 对样式隔离的行为,那么 Angular 又是如何做到这些的呢?
在应用启动时,Angular 将通过 styles 或 styleUrls 组件属性来查看哪些样式与哪些组件相关联。之后Angular 会将这些样式和该组件中元素特有的属性应用到一起,将生成的 css 代码包裹在一个 style 标签中并放到 header 里。
以上就是 Angular 样式封装的原理。
在实际开发中,这种机制有时候并不能完全匹配我们的需求,针对这种情况, Angular 引入了几种特殊的选择器。
使用 :host 伪类选择器,用来作用于组件(宿主元素)本身。
比如,当我们想给 app-blue-button
加个边框时,可以在这个组件的样式中添加如下代码:
:host { display: block; border: 1px solid red; }
通过查看运行时的代码,可以看到如下代码块:
<style> [_nghost-yke-c11] { display: block; border: 1px solid red; } </style>
有时候,基于某些来自组件视图外部的条件应用样式是很有用的。 例如,在文档的 <body>
元素上可能有一个用于表示样式主题 (theme) 的 CSS 类,你应当基于它来决定组件的样式。
这时可以使用 :host-context()
伪类选择器。它也以类似 :host()
形式使用。它在当前组件宿主元素的祖先节点中查找 CSS 类, 直到文档的根节点为止。在与其它选择器组合使用时,它非常有用。
在下面的例子中,会根据祖先元素的 CSS 类是 blue-theme
还是 red-theme
app.component.html
et remplacez-le par le contenu suivant : import { Component } from '@angular/core'; @Component({ selector: 'app-btn-theme', template: ` <button class="btn-theme">Button</button> `, styles: [` :host-context(.blue-theme) .btn-theme { background: blue; } :host-context(.red-theme) .btn-theme { background: red; } `] }) export class BtnThemeComponent { }
app.component.css < /code> Ajoutez le contenu suivant : <p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:html;toolbar:false;"><div class="blue-theme">
<app-btn-theme></app-btn-theme>
</div></pre><div class="contentsignin">Copier après la connexion</div></div></p>Il y a le code html suivant lors de l'exécution : 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:css;toolbar:false;">:host ::ng-deep h2 {
color: yellow;
}</pre><div class="contentsignin">Copier après la connexion</div></div><div class="contentsignin">Copier après la connexion</div></div>🎜Vous pouvez voir qu'il y a un fichier nommé <code>_nghost-ydo-c11 sur le <code>app-root< /code> attribut (propriété) de l'élément
, les deux éléments dans app-root
ont une propriété nommée _ngcontent-ydo-c11
. [Recommandation de tutoriel associée : "🎜tutoriel angulaire🎜"]🎜🎜Alors, à quoi servent ces attributs ? 🎜🎜Pour une meilleure compréhension, nous créons d'abord un composant indépendant et créons un nouveau fichier blue-button.component.ts
avec le contenu suivant : 🎜[_nghost-yke-c12] h2 { color: yellow; }
app.component.html < /code> Après l'exécution, vous verrez le code html suivant : 🎜🎜<img src="https://img.php.cn/upload/image/589/427/833/1625454095297965.png" title="1625454095297965 . png" alt="Une brève discussion sur le principe de fonctionnement des styles de composants dans Angular"/>🎜🎜Vous pouvez voir que <code>app-blue-button
a également un attribut commençant par _nghost-xxx
, et un autre The mêmes attributs que les autres éléments de app-root
. Les deux éléments du composant ont des attributs nommés _ngcontent-yke-c11
. 🎜🎜Étant donné que les chaînes d'attributs générées par Angular sont aléatoires à chaque exécution, si des attributs similaires apparaissent dans le code suivant, ils correspondront à cette capture d'écran. 🎜
_nghost_xxx
_ngcontent_xxx
blue-button<. de cette façon, la classe /code> ne peut être appliquée qu'aux éléments avec cet attribut et n'affectera pas les éléments des autres composants. 🎜🎜Maintenant que nous connaissons le comportement d'Angular en matière d'isolation de style, comment Angular y parvient-il ? 🎜🎜Lorsque l'application démarre, Angular verra quels styles sont associés à quels composants via les propriétés du composant styles ou styleUrls. Angular appliquera ensuite ces styles et attributs uniques aux éléments du composant, enveloppera le code CSS généré dans une balise de style et le placera dans l'en-tête. 🎜🎜<img src="https://img.php.cn/upload/image/290/386/580/1625454149362153.png" title="1625454149362153.png" alt="Une brève discussion sur le principe de fonctionnement des styles de composants dans Angular"/>🎜🎜Ci-dessus C'est le principe de l'encapsulation de style angulaire. 🎜<h2><strong>:host, :host-context, ::ng-deep</strong></h2>🎜Dans le développement réel, ce mécanisme ne correspond parfois pas entièrement à nos besoins pour ce genre de cas. , Angular introduit plusieurs sélecteurs spéciaux. 🎜<h3 data-id="heading-4"><strong>:host</strong></h3>🎜Utilisez le sélecteur de pseudo-classe :host pour agir sur le composant (élément hôte) lui-même. 🎜🎜Par exemple, lorsque nous souhaitons ajouter une bordure à <code>app-blue-button
, nous pouvons ajouter le code suivant au style de ce composant : 🎜rrreee🎜En regardant le code d'exécution, vous peut voir le bloc de code suivant : 🎜rrreee<body>
du document qui représente un thème de style, et vous devez styliser le composant en fonction de cela. 🎜🎜Vous pouvez utiliser le sélecteur de pseudo-classe :host-context()
à ce moment. Il est également utilisé de la même manière que :host()
. Il recherche les classes CSS dans les nœuds ancêtres de l'élément hôte du composant courant, jusqu'au nœud racine du document. Il est très utile lorsqu'il est combiné avec d'autres sélecteurs. 🎜🎜Dans l'exemple suivant, le CSS qui prendra effet sera déterminé selon que la classe CSS de l'élément ancêtre est blue-theme
ou red-theme
. 🎜rrreee🎜Ensuite, où il est utilisé : 🎜rrreee🎜L'arrière-plan du bouton est bleu lors de l'exécution. 🎜我们经常会使用一些第三方 UI 库,有时候我们想改变第三方组件的一些样式,这时候可以使用 ::ng-deep,但是要注意,Angular 已经把这个特性标记为已废弃了,可能在未来的版本就被完全移除掉。
:host ::ng-deep h2 { color: yellow; }
通过查看运行时的代码:
[_nghost-yke-c12] h2 { color: yellow; }
可以看到,样式会作用在 app-root
里的所有元素上,包括 app-root
中使用的其他组件里的元素。
在实际开发中,灵活使用以上几种方式,基本上可以满足大部分场景。
更多编程相关知识,请访问:编程教学!!
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!