在 Angular 中有两个特殊的选择器:
:host
:host-context
大概说明一下:
: host
使用 :host 伪类选择器,用来选择组件宿主元素中的元素(相对于组件模板内部的元素)。
:host 选择是是把宿主元素作为目标的唯一方式。注意:宿主不是组件自身模板的一部分,而是父组件模板的一部分。
要把宿主样式作为条件,就要像函数一样把其它选择器放在 :host 后面的括号中。
当再次将宿主元素作为目标的时候,只有当其带有同样的名称的时候,在会生效。
: host-context
有时候,基于某些来自组件视图外部的条件应用样式是很有用的。 例如,在文档的 元素上可能有一个用于表示样式主题 (theme) 的 CSS 类,你应当基于它来决定组件的样式。这时可以使用 :host-context() 伪类选择器。它也以类似 :host() 形式使用。它在当前组件宿主元素的祖先节点中查找 CSS 类, 直到文档的根节点为止。在与其它选择器组合使用时,它非常有用。
使用这两种选择器
创建两个组件:style-demo & style-demo-child
执行命令:
ng g c style-demo
ng g c style-demo-child
wujiayudeMacBook-Pro:pages wjy$ ng g c style-demo
CREATE src/app/pages/style-demo/style-demo.component.less (0 bytes)
CREATE src/app/pages/style-demo/style-demo.component.html (29 bytes)
CREATE src/app/pages/style-demo/style-demo.component.spec.ts (650 bytes)
CREATE src/app/pages/style-demo/style-demo.component.ts (285 bytes)
UPDATE src/app/pages/pages.module.ts (2145 bytes)
wujiayudeMacBook-Pro:pages wjy$ ng g c style-demo-child
CREATE src/app/pages/style-demo-child/style-demo-child.component.less (0 bytes)
CREATE src/app/pages/style-demo-child/style-demo-child.component.html (35 bytes)
CREATE src/app/pages/style-demo-child/style-demo-child.component.spec.ts (686 bytes)
CREATE src/app/pages/style-demo-child/style-demo-child.component.ts (308 bytes)
UPDATE src/app/pages/pages.module.ts (2263 bytes)
修改 style-demo 和 style-demo-child
修改 style-demo 模版文件
<h3>组件的样式demo--host选择器</h3>
<h3>组件的样式demo--host-content选择器</h3>
<app-style-demo-child [class.isChoose]="isChoose">
<h3>组件的样式ng-content 的内容</h3>
</app-style-demo-child>
<button nz-button (click)="handleChoose()">改变子组件的状态</button>
<button nz-button (click)="handleShiftTheme()">更换主题</button>
修改 style-demo 类文件
import {Component, HostBinding, OnInit} from '@angular/core';
@Component({
selector: 'app-style-demo',
templateUrl: './style-demo.component.html',
styleUrls: ['./style-demo.component.less']
})
export class StyleDemoComponent implements OnInit {
public isChoose = false;
public isYellow = true;
constructor() {
}
ngOnInit() {
}
@HostBinding('class') get componentClass() {
return this.isYellow ? 'theme-yellow' : 'theme-red';
}
// 设置 组件的状态
public handleChoose(): void {
this.isChoose = !this.isChoose;
}
// 更换主题
public handleShiftTheme(): void {
this.isYellow = !this.isYellow;
}
}
在 style-demo 的样式文件 增加两个主题
:host-context(.theme-yellow) {
h3 {
border: #e1a82c 2px solid;
}
}
:host-context(.theme-red) {
h3 {
border: #e1282d 2px solid;
}
}
修改 style-demo-child 模版文件
<h3>组件的样式demo-child--host-选择器</h3>
<ng-content></ng-content>
修改 style-demo-child 样式文件
:host {
display: block;
border: 1px solid #268ce1;
}
在style-demo组件样式中,通过:host-context以函数的形式 设置了两种主题: theme-yellow & theme-red
此时运行页面如下:
使子组件上 style-demo-child 的isChoose样式生效
- 第一种方式:在 style-demo 中设置样式
在 style-demo 的模版文件中,发现对 style-demo-child 设置了一个样式:isChoose ,这个样式只有在 style-demo中的成员变量 isChoose 为true时才会生效。
再次 修改 style-demo 的样式文件,增加isChoose的样式
:host-context(.theme-yellow) {
h3 {
border: #e1a82c 2px solid;
}
}
:host-context(.theme-red) {
h3 {
border: #e1282d 2px solid;
}
}
.isChoose {
border: 5px solid #56e12b;
}
此时点击按钮 – 改变子组件的状态,发现效果为:
此时发现 isChoose 的样式已经加上了
- 第二种方式:在 style-demo-child 中设置样式
先注释 style-demo 中的 isChoose 的样式,在 style-demo-child 中设置同样的样式,为了区别,此时设置为蓝色
修改 style-demo-child 的样式文件
:host {
display: block;
border: 1px solid #268ce1;
}
.isChoose {
border: 5px solid #268ce1;
}
保存运行
发现此时的 isChoose 并不生效,究其原因是因为 isChoose这个样式时属于 style-demo-child 的宿主的(即style-demo)此时就用到了 :host的选择器
修改 style-demo-child 的样式文件
:host {
display: block;
border: 1px solid #268ce1;
}
:host(.isChoose) {
border: 5px solid #268ce1;
}
//.isChoose {
// border: 5px solid #268ce1;
//}
此时发现 isChoose这个样式 生效了
那此时问题来了:谁的优先级高?
通过上面的运行发现 是在父组件里设置的 isChoose和通过 :host(.isChoose) 设置的样式都可以生效,但是谁的优先级高呢?
将之前注释在父组件中的 isChoose 样式恢复
修改 style-demo 样式文件
:host-context(.theme-yellow) {
h3 {
border: #e1a82c 2px solid;
}
}
:host-context(.theme-red) {
h3 {
border: #e1282d 2px solid;
}
}
.isChoose {
border: 5px solid #56e12b;
}
运行发现:
所以:通过:host选择器设置的样式优先级高
通过 host-context 来设置主题
在 style-demo 的样式文件中,设置了两种样式:theme-yellow & theme-red ,在类文件中,通过装饰器:HostBinding 来更改。
HostBinding 是用于把一个 DOM 属性标记为绑定到宿主的属性,并提供配置元数据。 Angular 在变更检测期间会自动检查宿主属性绑定,如果这个绑定变化了,它就会更新该指令所在的宿主元素。
这里是设置了 宿主的class属性,在isYellow 属性为true时,设置宿主元素的class属性的值为 theme-yellow,在isYellow 属性为false时,设置宿主元素的class属性的值为 theme-red.
-
黄色主题
-
红色主题